This is a follow up to the discussions about Human-readable Machine-verifiable Transaction requests from FEM Berlin Council from last weekend which are related to the EIP-1138 and ERC-681 and also Radspec implementation.
EIP-1138: Human-Readable Transaction Requests
ERC-681: Representing various transactions as URLs
Radspec is a safe alternative to Ethereum’s natspec
The people present at the discussion were:
Pedro Gomes @pedrouid
Mikhail Dobrokhvalov @Dobrokhvalov
Johann Barbie @johba
Remco Bloemen @Recmo
We discussed the use-case for transaction requests describing in more detail what were functions being called without prior knowledge from the wallet of the smart contract.
A lot of the assumptions of the current implementation is for wallets to know the ABI and source code of the Dapp the user is interacting or simply ignoring this all together and not providing any details about the transaction data.
Right now, you simply approve transactions (for example with Metamask) without knowing the exact intent of transaction that is signed.
The proposal for Human-readable Machine-verifiable Transactions requests has the goal to provide enough information to the user to make sure what they are signing is intended but at the same time it has to be machine-verifiable so that it can’t spoofed by a malicious Dapp.
We explored ERC-681 where you are able to use a URI format to explicitly declare the function called and its parameters to best describe the intent of the transaction.
Consequently we looked into Radspec to verify that the function and parameters described were correct and would produce the intented state change.
However we concluded that the ABI isn’t safe enough to verify that it matches the deployed contract and it could be spoofed to mistake the user into approving an unintended state change. Because despite the ABI describes the name and type of the parameters, it’s possible to lie about the name of a parameter because only the type is necessary to execute the transaction hash.
Using the Radspec README example for providing human-readable transaction requests
const call = {
abi: [{
name: 'multiply',
constant: false,
type: 'function',
inputs: [{
name: 'a',
type: 'uint256'
}],
outputs: [{
name: 'd',
type: 'uint256'
}]
}],
transaction: {
to: '0x8521742d3f456bd237e312d6e30724960f72517a',
data: '0xc6888fa1000000000000000000000000000000000000000000000000000000000000007a'
}
}
We have a function called multiply
which takes two parameters a
and b
which are both of type uint256
. Allowing us to describe a function that the transaction request intends to multiply a
and b
but the execution for this function only requires us to call it by hashing multiply(uint256, uint256)
thus a malicious app could spoof the parameters names to deceive the actual intent of the function without compromising its execution. So it could call the parameters b
and c
instead deceiving the user from the real execution of these parameters.
The proposed solution for this problem involves building an infrastructure that allows the comparison of the ABI against the source code of the smart contract. This was described as registry on-chain that would link to an IPFS address that would include the data to re-compile the smart-contract and verify the metadata hash with the deployed smart contract.
The data required to store on IPFS would be the source code, compiler version and optimisation settings. This compilation would have to be run off-chain for example using TrueBit protocol. This would allow to verify the ABI provided by the Dapp matches the deployed smart contract using the metadata hash comparison.
This was as far as the discussion evolved. The consesus was clear that exisiting infrastructure wouldn’t allow to make Human-Readable machine-veriable transactions requests without the access to the source code. Etherscan is currently the biggest source for source code for smart contracts but in order to make it decentralized we chose IPFS for hosing this data.
A proposed incentive for smart contracts to upload their source code to IPFS for allowing this verification was that it provide a “seal of approval” or “verified” badge at a Wallet level, giving a bigger assurance to users that this Dapp is confirmed to execute as intended. This was compared to the HTTPS green secure badge used by websites and would be not only a UX feature but a security feature.