Roadmap
Here are some areas of improvement and questions to think about for the next version of fallback(). Contributions are always welcome!
Tests
As of this writing, test coverage is pretty limited. The parts of fallback() that are in greatest need of better tests are:
the utility libraries — those in
src/integers/
andsrc/strings/
the core HTTP request parsing code in
HttpMessages.sol
.While
HttpMessages.sol
generally seems to perform well on simple, well-formed requests, its performance on malformed and more complex HTTP requests isn't well-tested.
Gas Optimization
The initial fallback() code was written with limited attention to gas optimization, and there are likely many places in the contracts where gas usage could be cut down. For example:
StringConcat.sol
— in many cases, theStringConcat.concat
function is just used to create intermediate strings which are subsequently concatenated again. Is it possible to "concatenate by reference" and only allocate a new string once the final concatenated result needs to be used?
Security
There are two parts to this — contract security and web security.
Contract Security
There's a Solhint rule called no-complex-fallback
, under the "Security" category, which encourages the fallback
function to have less than 2 statements.
- What are the security implications of making the
fallback
function so complex and open-ended in this project?
Web Security
Right now, all HTTP requests and responses are publicly accessible (if the contract is eth_call
ed) or written in plaintext on-chain (if we use eth_send*
). This makes this app unsuitable for sending sensitive/authenticated information (e.g. a JSON Web token, or user data) over the wire. What do we need to do to make this possible?
See the Encrypted Requests/Responses section for more details.
Examples and Documentation
Some ideas for improvements in documentation or examples:
- Would it be possible to write TodoMVC or something similar using fallback()?
- Are there any other canonical web app examples we could implement in fallback()?
Code Clarity
There are places in the code where it isn't exactly clear why something is working (but it still seems to work fine!). For example:
It is unclear why the
fallback
function inWebApp.sol
needs to return 32 extra bytes forsafeCallApp
inHttpHandler.sol
to receive the 404 response correctly when a nonexistent route handler function is called (when the 32 bytes aren't added, ABI-decoding the returned data into anHttpMessage.Response
insafeCallApp
fails).Author's note: As I was developing the
fallback
function inWebApp
and trying to figure out why ABI-decoding was failing insafeCallApp
onHttpHandler
, I decided to compare the returndata offallback
(again, onWebApp
— not the mainfallback
function onHttpProxy
) to that of a function which already existed onWebApp
.I noticed that when an existing function on
WebApp
was called, the returned data had 32 extra bytes at the end versus the returned data from thefallback
function onWebApp
. So I changed the assembly to return 32 extra bytes fromfallback
onWebApp
. Once I did that,safeCallApp
onHttpHandler
started decoding the return value correctly into anHttpMessage.Response
.The exact reason why these bytes needed to be added probably has something to do with the specifics of the
return
opcode and the ABI encoding spec for dynamicbytes
arrays, but (simply content with it just working for now) I haven't looked deeply enough to figure out the specific reasons why.
Extensions
Some ideas for further work:
Encrypted Requests/Responses
A major limitation of the contract as written now is that if run in send
mode (i.e. mutating the blockchain), it "logs" all HTTP requests on-chain as input data and HTTP responses on-chain as output data.
See the todo app contract's transactions on Etherscan for an example of the data that is written on-chain.
- What would it take to maintain the same HTTP request/response functionality while encrypting requests?
- Can we implement HTTPS on-chain, or is there some sort of more blockchain-native zk-SNARK solution we can use?
Other Protocols
Some other protocols that could be implemented Ethereum using the same fallback
function idea: