How the Lattice1 Makes Transactions Readable with ABI Decoding

What does ABI decoding mean?

The acronym, ABI, stands for Application Binary Interface. ABIs define how data is formatted when it is used to call a function on an Ethereum smart contract. More generally, ABIs are used for all EVM based chains, which include Binance Smart Chain, Avalanche C-Chain, Optimism, Arbitrum, and more.

Without ABIs, users have no reasonable way to interpret the message they are signing in the transaction request. This opens up many attacks and reduce the benefit of using a secure hardware wallet such as the Lattice1. Fortunately, Lattice firmware is able to use ABIs to decode calldata and display it in a more readable way. This decoding is done automatically as long as you are using an integration that leverages this encoding, such as MetaMask or Frame.

Basic ABI decoding demonstrated on the Lattice1

Starting in Lattice firmware v0.15.0, ABI decoding is done automatically for all contracts on the Lattice and comes with the device firmware itself - no need to install anything.

Here is an example of the raw calldata in a simple transaction. Can you figure out what's happening by looking at this hexadecimal string?

This raw data is unintelligible, which makes transacting with large amounts of value quite dangerous. If you can't read what you're signing, how can you be sure you aren't being attacked and that you won't accidentally send a bunch of coins to your attacker?

Fortunately, your Lattice can help. Using the large display and our advanced ABI decoding features, this obfuscation is a thing of the past. Here is that same transaction decoded and displayed on the Lattice1's screen:

This screen shows us that the user is sending a single DAI token to a friend. Let's break down what each field of this transaction request decoded on the Lattice1 means:

  1. This section includes all the basic transaction fields

    • Signer: The account/address from which the transaction is being requested.

    • Nonce: A special number that acts as a transaction counter in each account.

    • Gas: How much gas will be used in this transaction.

    • Gas Price: Current gas price determined by network conditions, this is ETH burned permanently.

    • Tip: A tip paid to the validator who includes your tx into the next Ethereum block.

  2. The contract field here shows the which contract is being called in the transaction request. The user here has set up an address tag in the Lattice Manager so the DAI contract appears as "DAI" instead of 0x6B175474E89094C44Da98b954EedeAC495271d0F.

  3. This amount refers only to an amount of ETH being sent, gas not included.

  4. This is the decoded calldata. Double brackets [[]] denote a function within a contract being called and single brackets [] denote the inputs being fed into those functions. Here, the user is calling the DAI contract's transfer function and the inputs [dst] and [wad] are the destination and amount fields for the transfer function. These have "britten.eth" and "1.0 * 10 E18" as their respective inputs. Again, the user has set up an address tag so that 0xf6868a79e20a48eff2bd7688402cc5ea40133883 appears as "britten.eth".

NOTE: 1.0 * 10E18 is scientific notation, which indicates you are sending 1,000,000,000,000,000,000 units of DAI (1 followed by 18 zeroes). That sounds like a lot, but this is what we call "atomic" units, as opposed to "observed" units. To determine the unit conversion, you have to look up the contract's decimals value. DAI, and most other tokens (including ETH), use 18 decimals. This means means 1E18 atomic units equal 1 observed unit, i.e. "1 DAI".

For a deeper look into how our advanced ABI decoding feature works, please see the Advanced ABI Decoding article.

Last updated