The Structure of an LLL Contract — Part 1

Constructors and functions and code, oh my!

Daniel Ellison
ConsenSys Media
5 min readMay 31, 2017

--

In this series of articles we’ll examine the structure of an LLL contract, describing its parts and on occasion comparing it to the structure of a Solidity contract. I’ll use a modified version of the example contract in my article/screencast pair entitled Compiling an LLL Contract for the First Time. This time the source is structured in a more readable way, includes a constructor, and has been split into two files. It also has comments! As usual, there’s a companion screencast for those who prefer a more hands-on approach to learning. This is going to be far more technical than any of my previous articles, but the end result will be a much deeper understanding of LLL, Solidity, and the Ethereum Virtual Machine (EVM).

Source code structure

All code has a structure. It may not be apparent to the observer, but there must be structure in order for a compiler to do its job and parse your source code unambiguously. Some languages use white space to indicate structure, some use a variety of delimiters, including braces, and some use only parentheses. LLL is firmly in the parentheses camp. Because there are visible delimiters in LLL — as opposed to white space as in Python — you could make your code quite unreadable by writing everything on one line, which illustrates why making the structure of your code obvious is so important. Here’s the example contract from the Compiling… article in one line:

Contract structure

The structure I’m actually concerned with in this article is that of an LLL contract and its various parts. It’s quite different from the structure of a Solidity contract. These differences can reveal underlying functionality that Solidity hides. This will give you a better sense of what’s going on behind the scenes in the Solidity compiler.

An LLL contract is always a single expression. This expression could be as simple as a single number or as complex as a deeply nested hierachy of expressions wrapped in expressions wrapped in expressions. For example, this is a completely valid Ethereum contract: 42. That’s right, an integer is a valid contract in Ethereum. If you run that through the LLL compiler it produces this bytecode: 602a, which in assembly is PUSH1 0x2a. So all the contract does is push 42, or 0x2a in hexadecimal, onto the EVM stack.

However, you usually want to do something a little more complex. LLL requires that any sequence of expressions be enclosed in a control structure. That could be while, if, for, or any other operator that encloses a sequence of expressions. If your code doesn’t need a control decision made, you can use seq to enclose expressions; seq was created for exactly this purpose.

Since an LLL contract is always a single expression, multiple expressions need to be enclosed in a control structure. And since a contract usually contains multiple expressions, it follows that a contract has to be enclosed in a seq expression. Here’s a simple example:

This returns 42 to the caller when invoked. It compiles down to 602a60005260206000f3 which translates to the following assembly code:

As you can see, seq is meant as instruction to the compiler and leaves no artifacts in the compiled bytecode.

The preceding examples can’t be deployed to an Ethereum blockchain using standard methods; the web3 environment expects a contract to have a certain structure, which brings us to the subject of this series of articles.

INIT and CODE

Now that we know a contract is always enclosed in a seq, let’s get down to examining what’s between the parentheses. There are two main structures in any LLL contract that adheres to the Ethereum Contract ABI. In theory, your contract can do anything; if you really wanted to, you could define your own method of deploying a contract and calling its functions. For our purposes, following the ABI standard allows our LLL contracts to take part in the Ethereum ecosystem in the same way that a contract written in any other EVM language does.

With that in mind, I can say that the structures in LLL are entirely conceptual. There’s no constructor function; in fact, there are no functions at all! We adhere to the ABI in order that our LLL contracts appear to have functions. One concept that is reflected in LLL contracts is the idea of deployment vs. invocation: these two distinct steps dictate the organization of your contract. Insofar as LLL has conventions, it’s customary to mark those two sections separately with the comments INIT and CODE. If you take a look at the banner graphic for this article you can see examples of both.

Roughly, the INIT and CODE sections of an LLL contract correspond to a Solidity contract’s constructor and functions. Behind the scenes, the constructor is executed when your contract is deployed. The deployment process only deploys your functions, not the constructor. This is why the constructor can only be executed once in Solidity and why constructor overloading is not supported: the constructor is not deployed to the blockchain. This will be made very clear when we explore the INIT section in the next article.

Conclusion

All those words and we didn’t even get to any real code! I expect this series of articles will take three or four parts to properly cover the subject matter. You’ll see lots of code in the upcoming parts of this series. See you next time!

Read More:

An Introduction to LLL for Ethereum Smart Contract Development
Building and Installing Ethereum Compilers

Compiling an LLL Contract for the First Time
Deploying Your First LLL Contract — Part 1
Deploying Your First LLL Contract — Part 2
The Structure of an LLL Contract — Part 2
The Structure of an LLL Contract — Part 3

Like this piece? Sign up here for the ConsenSys weekly newsletter.

Disclaimer: The views expressed by the author above do not necessarily represent the views of Consensys AG. ConsenSys is a decentralized community with ConsenSys Media being a platform for members to freely express their diverse ideas and perspectives. To learn more about ConsenSys and Ethereum, please visit our website.

--

--