What is the Blind Signing Problem?
Blind signing refers to any situation where a user is asked to sign a transaction without having visibility into the transaction’s contents. This lack of visibility could be due to limitations in the device (the hardware wallet blind signing problem), or be a ramification of the design of the blockchain itself. It is this point that I will focus on today.
But first let’s make it clear that this is not an esoteric problem that only exists on paper. Multiple attacks have occurred, for example:
The basic strategy is to compromise a social media channel and announce an airdrop or other benefit to holders of a specific token or NFT. To claim the airdrop click a link and follow the instructions. The instructions require that the holder prove ownership of the token or NFT. The only absolutely certain way to do so is to have holders sign the transaction that transfers the airdrop tokens with the wallet that is holding the original token or NFT. Up to now, this is normal procedure for this kind of thing. However, the catch is that the transaction provided for the wallet to sign transfers all assets in the wallet to the attacker rather than offering an airdrop.
There is a fundamental result in computer science called “the halting problem”. It basically asks, “given a particular computer program and input, will this program ever end?” It has been shown that this is undecidable – in other words, you can’t write a program that can analyze any other program and figure that out. This result is really important because although it was stated as “will a program halt?”, it’s easy to see that the result applies to any function – send you an airdrop, steal your coins, etc.
Since the Ethereum virtual machine is turing complete we can realize that it’s impossible to determine what a contract will do without running it. Could it be possible to recognise a subset of contracts? Certainly, but again some issues of how Ethereum works makes this harder. First, since the EVM is a general purpose computer with a blockchain database, each contract implements token ownership in its own manner. So one would need to special case each token type. Even though one could speculatively execute the contract (in a "sandbox" containing the full ETH state) to figure out what it does, the end result would be a set of bytes that are changed in the contract database. But what do those changed bytes actually mean? Understanding that would require a human.
In other words, you have to look at some arbitrary bit changes and somehow determine from them that a NFT was transferred. But you might respond that Bored Ape NFTs (or any other popular NFT) are so valuable that it would be worth it to write a custom checker for this exact NFT. We probably could -- but that would be a lot of skilled work. And it would still depend on the exact blockchain state of when the sandbox executed the contract verses when it was actually executed on the blockchain.
This observation leads to an attack, which I’ll call the state-race attack. It goes like this: Mallory (the attacker) constructs a contract that looks like this:
if (blockchain state X == 1)
{ doBenignThing(); }
else { doMaliciousThing(); }
Now Mallory sets X=1 onchain and waits for a victim by monitoring the blockchain for his contract execution. When he sees a target transaction appear, he quickly issues a high fee paying transaction that sets X=2. This higher fee tx is in a race condition with the victim’s transaction, and its high fee makes it more likely to be executed first, triggering the malicious behavior.
How is Nexa Different?
A few technologies make Nexa different. First, Nexa contracts cannot arbitrarily modify the blockchain. A transaction specifies a list of blockchain database modifications – these records are deleted, these records are added. This list cannot be buried deep in a turing complete contract execution – it is immutably defined outside of the transaction’s contracts, and easily accessible by a wallet.
So nothing that the contract can do can modify this list. Instead, it’s an all-or-nothing thing… contract execution determines whether the transaction is valid and the specified set of changes are committed, or not, and the changes are ignored.
Second, Nexa deployed Group Tokenization, which is a “native tokens” protocol. This means that tokens (and NFTs) are a primitive of the blockchain. Token ownership is specified in a standard manner, which is easily understood by wallets since it is an extension of how NEX ownership is specified.
In Summary
The end result is that a wallet can tell you exactly what a transaction will do before you sign it. The transaction’s effects are visible to the wallet, so we call them transparent transactions (or TTX). The wallet can say “you are sending 10 MEX, with a 1.50 NEX (1 million NEX = 1 MEX) fee and you are receiving 2 tokens”. And when a token type is created, additional information can be included which gives that token an icon, a ticker, a “home” url, a description and more. All of this can be presented to the wallet user before they choose to “Accept” or “Reject” the transaction proposal. So instead of the “blind signing” problems with EVM implementations, Nexa shines a light on all proposed transactions, letting you see exactly what’s going to happen.