One of the more eyebrow-raising aspects of Operate’s design is that Ops - the on-chain functions that power-up your Bitcoin transactions - are written using the Lua scripting language.
A few people have asked me, “why Lua?”, but this is a question that demands more than a 280 character tweet. So grab a cuppa and make yourself comfy whilst I explain how I settled on Lua and why I think it’s a good choice.
# Before Operate
At the beginning of 2019 I was working on an experimental project called Functional Bitcoin. This work was really just a learning exercise, and Operate is what Functional Bitcoin would have been if I knew then what I knew now.
The fundamental design of Operate and Functional Bitcoin are the same. Anyone is able to publish code on-chain, and any other party may end up loading and running that untrusted code. So in theory, attackers may publish malicious code in functions, and try to get other parties to run that code.
The solution to this problem is to sandbox the environment in which functions are run. If the functions can’t access the host’s file system, kill processes, make changes the the host’s environment, or access any sensitive data, there's little damage an attacker can cause. In the case of browsers, we need to prevent the functions from accessing the current origin’s cookies and local storage.
In Functional Bitcoin I made use of the
vm2 module, which is a very solid sandbox solution for Node.js, but not one that is usable in browser environments. I looked in to some convoluted solutions involving iFrames and web workers, but I’m not aware of any truly battle-hardened browser sandbox solutions.
# Enter Lua
It didn't take long for me to realise that Lua not only ticked all those boxes, it was pretty much the stand-out candidate. If you want to let users run in-process, Turing-complete scripts from untrusted sources, Lua is the best language for the job.
Lua was always designed to be embedded. Something like Operate is exactly the use case Lua excels at. Effective sandboxing is easily achieved, and due to Lua's simple lightweight design, it is a very easy language to learn.
There are a few other languages occupying a similar space to Lua, but I considered them all a bit too obscure. Lua is actually quite widely used in some surprising places - for example in nginx and Redis, in embedded hardware, and particularly in games and the game-modding scene - so has a reasonable ecosystem around it.
One difference that is relevant to Operate is how Lua handles binary data. Rather than using Buffers and converting to and from strings, in Lua strings are just sequences of individual bytes that can contain any arbitrary binary data. I prefer this - it means we can just read any data from Bitcoin transactions, and whether it is a UTF-8 string or some other binary data, we can use it in the same way.
# To the browser and beyond
That is why Lua.