Preface
Blockchain applications communicate with smart contracts via binary interfaces/protocols. This a protocol that translates contract calls e.g. order_beer(7)
to stream of bytes that the environment of the smart contracts (VM) can understand and execute. Also the protocol defines how return data from the smart contract calls should be decoded.
Definition of Terms
- HTTP Compiler - a thin erlang HTTP service wrapper for aesophia compiler
- Calldata encoding - serializing function name and arguments of a contract call to its binary representation
- Decentralized Apps (a.k.a daepps) - My opinion is a bit different than the popular one which consider only the smart contract itself as daepp. I assume all the layers and tools a user would need to use such an app. That includes the UI of the app, it also should be de-centralized e.g. deployed to decentralized system like IPFS or ad-hoc distributed to users as a bundle. That UI should be resilient to censorship (and any other SPOF) as well.
Status Quo
Back in the days a HTTP compiler was created to easy the adoption of the daepps and to safe some time from SDK developers to implement encoding/decoding themself. Also as 2019 was very rapid development year for the (core) protocol it would have been almost impossible for SDK developers to keep it up-to-date.
However, as the protocol is much stable now, I think it’s time to move forward.
Related public discussion: En-/Decoding - a currently fatal design flaw in æternity?
Value Proposition
Daepps written in javascript should be able to encode/decode contracts calldata/results without using external service a.k.a. HTTP compiler.
There are few main issues I see by using compiler service:
- Security - this should be considered highly trusted service as the daepps rely on it to provide encoded/decoded contract calls data. A malicious service operator can temper it all and trick the user of the daepp to sign whatever contract call they want without any way by the daepp to prevent that. This eventually will be noticed on-chain, once your account is empty already.
- High availability - if the service is down for whatever reason the daepp is not operational anymore. Remember how coronanews.org was stuck during a townhall demo ? Yep, the compiler service was overloaded.
- UI Centralization - by having the dependancy on the above service, it should be run somewhere server side, this automatically makes the daepp UI subject to censorship
- Performance - as this is HTTP service, each contract call implies 2 additional service calls to the compiler (encode calldata + decode call result). This is waste of user time, bad UX and waste of server resources
First 2 issues can be kinda worked around by hosting the service “yourself”, however this is waste of time and resources and need some technical skills, so users prefer to use “our public” service which imply a lot of trust and responsibility to us.
All of the above would be solved with this proposition.
Required Work
I started thinking and validating the concept at Sofia hackathon last year. I usually fall in love with binary protocols very easy, so I continued working on this mostly on my free time.
So I already have basic encoder that supports most of the types:
✔ Encoder › Encode implicit init
✔ Encoder › Encode empty arguments
✔ Encoder › Encode boolean arguments
✔ Encoder › Encode single int arguments
✔ Encoder › Encode multiple int arguments
✔ Encoder › Encode bytes arguments
✔ Encoder › Encode map arguments
✔ Encoder › Encode tuple arguments
✔ Encoder › Encode nested tuple arguments
✔ Encoder › Encode simple variant arguments
✔ Encoder › Encode variant arguments with non-zero arity
✔ Encoder › Encode type aliases
✔ Encoder › Encode records
✔ Serializer › Serialize booleans
✔ Serializer › Encode unsigned
✔ Serializer › RLP Encode Unsigned
✔ Serializer › Serialize integers
✔ Serializer › Serialize lists
✔ Serializer › Serialize maps
✔ Serializer › Serialize tuples
✔ Serializer › Serialize byte array
✔ Serializer › Serialize string
✔ Serializer › Serialize bits
✔ Serializer › Serialize variant
✔ Serializer › Serialize bytes
✔ Serializer › Serialize address
✔ Serializer › Serialize contract address
✔ Serializer › Serialize oracle
✔ Serializer › Serialize oracle query
✔ Serializer › Serialize channel
30 tests passed
What’s left
General tasks
- move to org repo, add licence
- re-organize file structure to be useful as standalone library
- setup CI
- change current testing framework to something that runs in a browser as well (currently using AVA)
- re-factor for better extensibility, maintainability and eventual work paralization
- full test coverage
Complete encoding
- maps serialization ordering
- nested maps
- nested lists
- template variables (i.e. a’ b’) use in variant types
- better error checking
Decoding
The same that has been and will be implemented for encoding, but in reverse (bytes → JS data)
Estimate
4 man-weeks (~160h)
I can’t commit for delivery date tho, as I’ve a lot of unplanned operational tasks that popup occasionally.
I’d also welcome some dedicated time for @hanssv.chain to help me with consulting and eventual general reviews. (He loves JS, but don’t tell anyone).
Known Limitations
- Javascript is not very nice language to work with big numbers, data structures and binary protocols. However, there are workarounds and acceptable solutions for it.
- Changes in the serizalition protocol has to be applied in this lib as well - a.k.a maintenance, however the protocol is quite stable so far.
Out of scope
This proposal is about standalone library and SDK integration is out of scope of the proposal.
Outlook
- better “decentralized” daepps
- more secure daepp frontends
- actually the daepp development, deployment and maintenance should be easier if we get rid of the HTTP compiler runtime dependancy