We recently sat down with Chief Technology Officer of Mysten Labs and Creator of the Move programming language, Sam Blackshear, to discuss why he developed a new smart contract programming language, the features that enable Sui to scale, and the benefits of decentralized technology for builders.
Can you start by giving an overview of what a programming language is, what qualities matter most to developers when looking at programming languages, and what drove you to develop your own?
A programming language is just a tool for interfacing with a computer in a way that is friendly and safe for humans but also efficient and unambiguous, and that part is especially important for a computer. We can't talk to computers in natural language because the whole point of natural language is that there's a richness and expressiveness to it. Like you say one thing in a slightly different tone or slightly different word choice and it will make your sentence or a paragraph completely different. Whereas in a programming language, the most important thing is that you have precisely defined semantics. And when you write a program, you know exactly what it's going to do. You make a small tweak to it, you know what that delta is going to be. And also that this is preserved for multiple levels, like you could write code in a source language and that has a meaning, it gets translated into an intermediate representation and that better have the same meaning, and the same thing all the way down to the silicon of the machine.
I think programming languages, unlike natural language, are inherently domain specific or task specific. Otherwise, there would just be one programming language and it could do everything. But the whole reason that multiple ones exist is because you can't be good at everything. And they're really trying to target specific problem domains and focus really hard on that. So if you look at, say, Rust, the programming language that we used to write the Sui blockchain and to do most of the other systems work we do at Mysten, it's focused on writing code that's really fast and extremely performant while also being safe. It lets you get at low level aspects of memory, the thread structure, or concurrency, but without letting you shoot yourself in the foot in the way that previous languages like C or C++ have done.
And so the story of Move is very much like that. When I created it, it wasn't a goal to create a new language. One of the other questions you asked is what developers look for in a language. They ask ”Is this good for the task that I want?” But I think maybe even more important is, “Does this language have a big community? Are there a lot of libraries available? Are there a lot of programmers using it? Are there good educational resources?” And because that part is so important, the bar for creating a new language has to be super high, like even if the language itself is way better, if it doesn't have this other thing, being better doesn't matter. And it's very hard to go from zero to having that really large and vibrant community.
Can you share more about the development of Move?
The origin of Move was at the Libra project at Facebook. The mandate that I had wasn't to create a new language, it was “Libra needs to have smart contracts so figure out what we should do.” And I looked at all sorts of things. Could we use Solidity in the EVM? Should we use a conventional, general purpose language like WASM or the JVM and use that for Libra? Or should we create our own thing? And the decision to create our own thing was based on studying existing smart contracts and understanding what programmers are trying to do, and where the language was helping them and where it was letting them down. The conclusion that I had is, it's really letting them down in a lot of cases.
This was clear from Solidity's poor security track record, but also, maybe even more fundamentally, is that these smart contracts are very unconventional kinds of programs. And Solidity wasn't a language built to do what people do today. I don't mean this to be critical, because they were the first smart contract language and they didn't know what folks wanted to do with it. Once you see what folks are trying to do with it, I think it's very clear that you want a different set of abstractions and programming tools than the Solidity language is providing.
So these smart contracts, they're very simple. They basically do two things. They define the shape of assets, including rules for when they can be transferred, what you're allowed to do with them, who can read them, who can write them. And they check access control policies for who has this asset, who's allowed to spend it, who is allowed to do something with it. Everything is about the assets, and you want these assets to have the same properties you have with physical assets. If I hand something to you, then you should have it and I shouldn’t have it anymore.
There's this notion of ownership and ownership transfer, but on a computer, everything is just bits and bytes and can be freely copied. And, you know, these concepts don’t exist. So you want to have a language that gives you those nice abstractions around ownership and around fungibility. Just like you would have in the physical world but without forcing the programmer to reinvent that. You want those basic safety guarantees.
So that's what Move does and why we ended up creating a new language. There are these tasks that are fundamental to smart contract programming. They're hard to recreate in other languages, including existing smart contract languages, and we wanted to design the entire language around providing these primitives so programmers can write code safely and efficiently and not have to reinvent the wheel every time they want to write some code.
Sui uses a variant of Move, called Sui Move. What prompted those changes? And what qualities of Sui Move are uniquely suited for building products in Web3?
There were a couple of things that motivated those changes. One is that the original Libra project’s goal was to build a compliant payments network. So we tried to design Move as a general purpose language. But we also intentionally did certain things because of the constraints that Libra wanted to have. One important thing was that they didn't want people to be able to take some assets and send them anywhere. They wanted people to explicitly create an account and have some rules around account creation, like maybe the owner of the account has to be KYC. Or maybe there’s a fee to create the account, or it can only be created by some small subset of folks who have the permission to create accounts. There were these restrictions because the whole point was that Libra wanted to do these compliant payments and compliant smart contracts. But in the more generic Web3 space, it's quite the opposite. You don't want to have compliance at the base layer, that's a smart contract concept. You want things to be as free as possible, you should totally be able to take something and send it to any address. And then you shouldn't have to do explicit account creation, because there's all sorts of use cases that would be blocked. That was one big factor.
And then another factor was that, although we had this nice focus on assets inside of Move, we weren't thinking at the time at Libra about how we bring that asset focus into the transactions themselves. And so it'd be like, it was great to write code in Move but then when you got to the transaction level, you still just have this API where you put in numbers and booleans and stuff that isn't assets, and then inside of Move, you take those numbers and use them to grab assets out of an account and do all this stuff. And it just turned out that a lot of the code you're running was this nasty bookkeeping, where it's like, get this thing out, get that thing out, get something else out, alright, I've got all the assets I want. They're here, in my studio, now I can actually start doing something meaningful. And then at the end of that you're like, okay, take the assets and put them back in this account, put them back in that account, reorganize them.
In Sui, we thought a lot about, well, if every program starts this way and ends this way, can we abstract that out? And so the logic for processing the transaction will do that for the programmer and from the programmer perspective, they just have the assets they need sitting there ready to do the interesting work right away. And that's what led to this object centered data model that exists in Sui. In the original Move, we had an account based data model where assets live under an account, and the programmer has to explicitly grab them. And in Sui, they come into the Move part of the transaction with assets already fetched by the Sui runtime. And that's both nicer for the programmer, because they don't have to do all this before and after bookkeeping, but also this is the secret sauce that allows us to see whether a transaction can be run in parallel with another transaction without actually executing it, to scale Sui horizontally, and to do a number of other things more efficiently.
We've done several other things that are quite interesting, like programmable transaction blocks that leverage the object based data model. That's a slightly more technical topic, and I'm happy to try to get into it. But those two things were the main motivator for the divergence from the original Move.
It would be great if you could share more about programmable transaction blocks and how they function.
The analogy I like to use here is that other blockchains are like a mall food court. You want to get some ice cream, you go to the ice cream stand, you whip out your credit card and pay for it. But then if you decide you actually also want a burger, and then you go to the burger stand and pay there as well. And I'm not a glutton, but if I wanted to eat eight things, I have to do eight separate transactions. Whereas Sui is much more of an all you can eat buffet. Every transaction isn't just one thing. Once you pay to get the buffet, you're able to do a lot of things without more cost. You can get an ice cream, you can get a burger, you can smash them together.
To make this a little bit less abstract, in the simple case of sending 100 transactions to mint 100 NFTs you can send one transaction that mints 100 NFTs. And that costs about the same as it would to mint one NFT. You can also do heterogeneous bundling of transactions, like the first transaction in a block takes a Mario character out of your multisig wallet and the second transaction in the block asks for a Mario and it lets you play a game. And then if you win the game and get a trophy, maybe the third transaction takes the trophy and puts it into a trophy case that you share with your friends. So the thing that's cool about that is that programmable transaction blocks allow programmers to write the code in such a way that the game doesn't have to be aware of the multisig wallet or how the Mario is stored. It also doesn't have to be aware of your trophy case or how that's implemented.
Programmable transaction blocks consist of these transactions where each has input and output objects. And if you have something that expects an input object, it can get that thing without caring about where it came from, and then also pipe its output into something that's expecting that without caring about where it came from. In other blockchains, there's a lot more coupling, so the game would have to integrate with the multisig wallet and with the trophy case, or they would both have to implement some common interface and have more coupling. Sui makes it a lot easier to do what I call ad hoc composition. It's just like, if the pipes match up, we can do it in one transaction.
And what are the benefits of programmable transaction blocks for users?
From the user side, I would say the benefits are lower gas fees, because instead of doing separate transactions, you can pack it all into one transaction. Also, fewer approvals. If you're using a system that requires transaction approvals, instead of doing three approvals you just do one, and then it does everything all at once. And then I think the other one would be atomicity, where if you're trying to do three different things, and you want to make sure that the third one only succeeds if the first two succeed, you can't do that if those things have to be separate transactions. But if you can put it all in one, then you can do that no problem.
I have heard you and others talk about how important it was that developing on Sui is a great experience for programmers. Do you have any anecdotes you can share about both experienced and new Web3 programmers starting to work with Sui Move?
I think for the folks coming from other Web3 programming languages, they really feel like they're a lot more productive in Move and Sui Move. And also it’s a lot safer. I was just on a podcast with the folks from the Bucket Protocol, they're building this very cool DeFi project on Sui. And they were going through the architecture of their system, showing the different boxes of how things work together. And what they were saying is if they were writing this in Solidity they feel it would have taken them eight months but with Sui Move they were able to do it in two, and they’re very, very confident in the safety of it. The way the language works just maps very closely to the ideas they have in their heads for how their project should go together. Whereas it's a lot more indirect in the Solidity space.
That's one example, but we've heard many, many cases like this where people say they are both a lot faster in this language and when I get done, I'm a lot more confident in the result. And that makes me happy to hear. But in some ways, it's not surprising. We looked at Solidity and looked at what the problems were. And we really designed explicitly around, how do we make this safer? How do we make this faster? How do we look at what the humans who are using this language are trying to do and how do we design what they want, rather than what they have? It’s all just us succeeding at that goal. This language was designed for the problems that people have so I think when they make the switch, they really appreciate that.
They say there's a first mover advantage, but I guess in this case, it's second mover advantage.
You sort of talked about this when you mentioned the object centric nature of Sui Move and Sui generally. But could you more explicitly draw the connection between the design of Sui Move, and the ability for Sui to fulfill the promise of mass adoption for Web3, particularly with low latency, low cost, and scale?
The thing in contributing to Sui that we're very wary of, which I think is a problem that other platforms struggle with, is if you have limited capacity, whether it's 15 TPS [transactions per second] like on Ethereum but even if it's 100 or 1,000, if it's a fixed number you're going to reach a point where if the platform is too successful then it maxes out the capacity. And at that point, the experience for everyone using the platform degrades. If there's only 1,000 slots, you have to pick which 1,000 are the most important so you do that via gas auction or something else. The prices go up for everybody or the latency increases for everybody, or both. A lot of use cases get locked out because the use cases that can pay the most win and everyone else has to go elsewhere or wait longer. It's not great.
The thing Sui is aiming for is horizontal scalability. If a certain amount of hardware is allocated, a certain amount of throughput can be achieved. And if more throughput is desired, validators can bring in more hardware. There's no upper limit to that. This is how every Web2 service works. I mean, there are engineering constraints that you have to figure out, it's not a certain or easy thing but everybody, when they're designing a scalable web service, wants horizontal scalability.
If Sui gets more customers or more users, the goal is for Sui to be able to keep growing and things should just work. And, of course, retain really low latency. You don't want the case of getting more throughput, but having to trade off latency.
On the Libra system, we didn't have these properties in mind. It was a small scale payment system with a couple of hundred payment operators with maybe thousands or millions of payments a day but not too many more. So we had a single box architecture because that's simpler and should be enough. With Sui, we knew the Libra system was not going to work because it doesn't have the horizontal scalability property. So we thought, how can we start from the ground up with a design that is going to be able to do that. And that's where the object centered data model came from. We sort of threw the old account based data model out the window, because that was the thing making it very hard to achieve horizontal scalability. Whereas if you organize everything around objects, your global state is just a big map from object IDs to objects. That's a key value store and we know how to scale a key value store. It's an easy engineering problem.
Then the question is, how do we have a transaction structure that fits into fetching stuff from a key value store and updating it? How can we shard the key value store? How can we decide where transactions should be processed? And so that's basically where it came from. It's like, this is something we know how to scale. How do we turn that into something that has the properties of a blockchain, the authenticated reads, working with Move, and all this kind of stuff. And then how do we just marry them together as smoothly as possible.
At a higher level, how do you talk about the promise of decentralized tech with skeptical Web2 developers?
I think of blockchains and crypto fundamentally as a technology for removing friction. There are barriers that are there so the way we transact financially, build applications, or set up information just makes it very hard to do things because there's no way for information to cross these barriers or, if they're crossed, they require the aid of some third party who's going to extract some rent for being able to do that.
The classic example that folks like to use is, if you're purchasing a house, there's a home buyer and a home seller, but when you actually do the payment, there has to be this escrow agent who does nothing except sit there and hold the money because the buyer and seller don't fully trust each other. That's just a reality of life. And it's something that we deal with. But, if the escrow agent can be code that both people can look at or is vetted by some third party, then it can do that job for free or for much less money. It's not the purpose of blockchain to eliminate escrow in real estate. That's one use case. But that's the general principle.
What if instead of having app A and app B, with no interoperability between them, they're built on the same rails, the same foundation platform, so you could have things flow from one app to another, whether that's in-app items, whether it's data, whether it's cross promotions, or some third party thing that builds on top of both. Or think about the web, sites share data with each other via cookies but these cookies are read-only metadata. What if these could be money? Or what if these could be spendable objects? What if this could be loyalty programs and coupons? And just everything has that built in. This is very abstract but this is the potential. Usually someone who's building will think these are new superpowers that I can use to build something more compelling.
For an end user, when they think about trusting code even if they aren’t technical, do you sense a hesitancy even if the other option is a large central entity that isn’t transparent?
I don't think so. Because we all do this every day, right? When I log into my email, I'm not very concerned that the code is going to be dropping one of my emails or not actually going to send something when I send it. If that happened, then probably I would stop using email, or use a different provider. I think it's very much the same here where, of course, only so many folks are gonna be able to really read something and check how it works. And you know, if I wanted to check that for email, I couldn't, because the code isn't there. So transparency is one big aspect of that. The fact that not everyone will be able to do it but some can spot check it. And then also with anything there’s repeated usage, in addition to immutability. That's the thing here. When I log into email, I don't know whether the code has changed since the last time I did something. There is no transparency around that. Even knowing that piece of information is something that you can get in Web3, you can't get elsewhere.
How do you expect Sui Move to evolve over time?
A lot of the features we're looking at now are based on our experience with the folks publishing their initial batch of Sui Move packages, and then seeing how they want to evolve them, and what things are easy to evolve and what things are hard. Sui Move is a very good language for publishing a package the first time, but the idea of having a package where I'm going to change this type around, I'm going to add some fields, I'm going to add some functions, I'm going to do this or do that and do it in a way that's cohesive, but also doesn't violate the trust of the users who were using the initial package becomes a very challenging problem. A lot of what we do is look at that and figure out what language level features we can add to both give programmers flexibility to extend while also preserving the trust for folks who used the original code.
We're looking at a number of features around that, especially enums. There's lots of other things we're doing around the experience of connecting Move to front end code. We like to joke that a typical Sui app is 5% Move code and 95% front end. So we care a lot about that 95%. We spend a lot of time talking about Move, but we care a lot about making that other part more productive and making that connection easier to make. And just generally, how can we make apps consist more of Move, so we get more safety? And then also how do we make that 95% of the code accessible to both Move programmers and non-Move programmers.