Recap Sui AMA: Move Programming Language with Todd Nowacki & Damir Shamanaev

Mysten Labs
Mysten Labs
Published in
25 min readJun 24, 2022

Note: You can find further information regarding Move Programming Language on our Sui Developer Portal.

Introduction

Jen: Thank you so much for tuning into our second installment of our AMA. This time the theme is our Move programming language. I’m really happy to introduce our lovely guests, Todd and Damir, our Move Programming Engineers at Mysten Labs!

Todd: My name’s Todd and I’ve been working on Move since 2018. I do the compiler stuff as well as Sui integration work.

Fun fact: I’ve been at Mysten since March and prior to this I was at Facebook (or Meta) for eight years. So it’s been fun in the startup space.

Damir: I’m Damir and I’ve been coaching and using Move since 2019 when the folks at Facebook were just developing the language. I’ve been through the first phase of Move IR and then started using Move. Before they had written any documentation for the language, I wrote the first book about the language.

Question #1: What is the history of Move and what sets it apart from other programming languages like Solidity?

Todd: As far as history, Move was created as the programming language for the Libra and the Diem project at Meta. Meta was looking at smart contract programming languages and trying to find something appropriate for the project and nothing really fit the bill. When we’re looking at other blockchain programming languages, namely Solidity, it doesn’t have assets or other blockchain items as first class items. In some ways, it looks like Javascript where you’re trying to build up programming your value from mappings, but it doesn’t really have an asset first programming model.

So, I started looking at these ideas from linear logic, linear programming, linear type systems, and integrating those as a way of introducing scarcity into a programming language. And that’s what Move really is — it’s a language for programming with scarcity.

We wanted to make sure that you have this built-in notion of: here are some values, these values represent real world assets, you shouldn’t be able to copy them, and you want to make sure that they’re used correctly.

We need this idea of scarcity, of programming that makes sure that the assets you have aren’t copyable, that you’re using them like you would use money, and they behave like physical money. You also need things like metering for a blockchain language. It’s important that you, if you come on to these platforms, you have to kind of pay for play or pay for the computation that you’re using, and have some mechanism for that. So, while you could take an existing language and try to add scarcity to it, or add an API or kind of programming with assets, it’s difficult to then also get metering.

Even more difficult on top of that is integrating determinism: a mechanism in a blockchain environment that requires all nodes to agree on the result of the computation (aka given the same input, you want the same output). You’d have to start really going through and banning a lot of libraries for non-deterministic behavior, like random number generation as an example.

So, we’re looking at all these things, and that’s really where Move got started. We thought: let’s just make a really simple language that has all of these things as the starting point of the primitives in the language. Move really started out as a very simple language for programming with resources or assets and we’ve added a bit of complexity over time. But that’s the history of it, and why we didn’t really take an off-the-shelf language like Solidity, or even Rust.

We started Move with a simplified language and made it object oriented. Then we adopted a more ML-like module system. A lot of it was designed with making sure that these blockchain applications were simple. From day one, another thing that was important, was being able to actually have strong guarantees, and being able to prove things about Move programs statically. We always had this goal in mind of building Move prover in some sort of static verification, because a lot of times when you come back, and you want to do static verification on the language, you have to deal with all this nastiness that the language added for expressivity, but isn’t really amenable to easy static verification. Originally Move wasn’t even Turing Complete; we didn’t have general loops, or recursion. We were hoping that that would make static verification easier, but it turned out that we really didn’t do that. One thing that we didn’t keep out of this language was dynamic dispatch, or kind of the more traditional thinking about object oriented languages where there’s no trace or anything. There’s no way of having indirect calls, or functions, where the behavior of the code path or what logic you’re taking is really purely dynamic in that way. This just makes certain parts of verification a lot easier. While you do have to program in a different way, we think that that trade off is worth it.

So the language has kind of evolved from that standpoint. We didn’t really have a generic set first language. There was no sort of polymorphism; that came later. There’s a lot of really fun stuff. If you ever are bored, just go and read through the VM or the IR; there’s a lot of really fun learning artifacts and they’re kind of fun archaeology. Move didn’t really have vectors or other collection types at first, we have this byte array type that was used everywhere, so you can think there are still some references, the byte array in the code base, which is always amusing.

I think that one of the things I’m proudest of is our reference safety checks, we have this borrow checker, you know, Rust’s very famous for having this borrow checker, that’s this static verification around references. And it’s famously for producing extremely confusing errors. And I’m not saying nothing confusing has ever come out of Move, but I think that in terms of the complexity of the system, we’ve produced something that has similar levels of expressiveness for the reference safety, while being, at least in terms of the formalism or implementation much simpler.

Damir: Back around 2019, we were developing a blockchain which was supposed to be a defi blockchain and we had to choose a language. At the time, you only had solidity and the other two options were up and coming development languages, one of which was Move and the other one was, if I’m not mistaken, was created by the guy who created crypto kitties.

Move first was a super bulky, hardly usable language because it was mainly, at the time, used in mobile AR, but it already had a number of properties and a number of ideas that actually drove me crazy. Then, a few months later, I completely fell in love with the language because of its expressive ability.

I come from a Solidity background and in Solidity you express stuff, like who owns something (I own NFT 1, you own NFT 2). It’s like a centralized HashMap or a database. As a database, you need to re-implement the database, but in Move, you could really own a type.

For example, whenever I say there is this coin, I own a type. It’s not written somewhere like in decentralized HashMap, but rather I literally own it. Now I think with types in my head. I know that if I pass this type coin somewhere, that means that I’m literally taking the coin from me and passing it somewhere else.

And this idea, I mean, once you get it, it’s like it opens like a lot of possibilities in like programming in general. So once you start thinking like objects and not thinking like abstractions that you build over programming primitives like a hash map, you always know what you’re doing, just like with unlimited expressivity with explicit stating of types — what was and still is.

I believe that is a selling point of Move, because you can express anything like you would in real life. When I’m at the bar explaining Move, I’d say, “So here is his bottle and here is this glass. Imagine both of them are NFTs and if we have a function, which would be like ‘pour water’ from this bottle to a glass, you literally pass this two together.” The function does it and returns you the full glass.

Question #2: Why did we select a variant of Move for Sui as opposed to using the standard Move language?

Todd: Yeah, so I guess just a bit of background here of how Move is set up. One of our goals was to build a purely language for scarcity. There’s not a lot of blockchain primitives or other things built into the language. If you go and look at solidity, It really is a language purely for Ethereum, there’s all these things baked in about various of block like the Ethereum native things that are a core part of the language and our goal was to make sure that Move felt like it can be instantiated on any sort of blockchain or any sort of application where you wanted scarcity.

But, we needed a way right to generalize storage. It’s helpful for blockchain, to be able to commit to state or actually write something down, you’re not just making the CPUs hot, you want to spend the gas, you want to make sure that you’re able to commit to a lender or make a change to the state.

So, Move have this idea of global storage that modules can declare resources or with types, and then index those into the chain and be like, Okay, I’m gonna take my coin type, and I’m going to move it and assign it or give it to this address, so we kind of had this little bigger hole map where your accounts and each account had resources and you can have one resource per type.

So, that was the goal of having a generalization around blockchain storage. But when it came to Sui, we’re trying to make a more efficient blockchain by recognizing that not every transaction is related and actually having this big centralized global state is a drawback, and it’s a drawback, but it doesn’t actually buy you much. If I’m sending a coin to Damir, the blockchain doesn’t need to wait around for me to also send some other coin to Jan or to someone else, these are independent transactions. But Move with the way that it was representing global storage these sort of concepts were very, very different or difficult to express, if not possible, because it was designed with a centralized account based model.

So to do this differently, we had to think back of like, how do we represent individual objects and Move? How do we take this sort of independence of data and insert it into the language? And I wasn’t there for the design of this, but early in the stages of the design Move, we thought about having all of the global storage instead of being this thing that you have access to these built in functions, we were thinking about it as maybe this would be a parameter that you pass into functions, you have like a, a storage type that you’re passing around in the language, and that’s basically the kind of concept that we went back to for Sui Move and instead of having centralized data as a part of primitive in the language, you will instead pass in the objects you want to consume to the entry point functions.

So that you explicitly say, Okay, I’m going to take an object of this type, and then under transaction level, you specify which object of that type you want so you have some the ID for it.

So really, that normal move is just not set up to be able to represent objects of this, and what we’ve done is remove the global storage, these big general, centralized storage from the language for Sui. I’ve gone to this individual object model so that this is really the way that or why we kind of needed to depart from standard mood, and the thing we’re doing differently.

Now, that being said, I just want to make clear, it’s not reformed to the language, or anything Move was built to allow individual adapters,that is individual instantiations of the language can add these sorts of things, by interfacing with the VM without having to actually import the language or do anything different.

So there are facilities we’re still using in the same standard library as other movements and creations. It’s the same kind of it’s the same VM, It’s the same Move Ling that we’re contributing to upstream, we’ve just taken a different approach for how we’re going to interface with storage.

Damir: You mentioned entry points, and it’s a bit enough of that. Do you know why everyone bailed on transaction as credits?

Todd: Yeah, we can talk about, going back to the history, they’re a little bit originally for one of the ideas for Move is, if you look at solidity, it’s really not like programming in a normal programming language, right? You go there and you build this synth, there’s no sharing of code. If you’re programming in a rust, and you want to go pull in some other crate or programming in Java, you can just import like from library something doesn’t really exist in solidity, at least not in the classical sense, right? You have to copy paste them code or pull in all these things, you can call out to other other contracts, but it’s not really like linking against code in a sort of normal way.

Goals for the Move module system is to behave more like a normal module system that you’d expect from other programming languages, so that if you want to reuse code on chain, you can do that without having to republish it.

Now, the question was, then how do we actually start transactions? So the idea was to basically have a separation, you have modules, which is the reusable code, and then a script is just like, I want to execute this series of instructions on the blockchain. Scripts are kind of like, they grew and grew over time to the point where they’re really looking like little mini modules, and as such, we’ve kind of transitioned a bit more into, instead of having necessarily scripts is like, here’s a set of instructions, please execute them on chain. Instead, in a module, you can specify to say, like, here’s like a transaction or here’s an entry point to execution, you can call this function in this module, you can kind of think about it as a reusable script. It’s a set of instructions published on chain that you can execute over and over again, as opposed to scripts, which were these throwaway collection of instructions.

So, that’s kind of where that’s coming up from and it’s really been helpful too in terms of programming in Sui for getting these kinds of objects, because now the model can define how you can program over the objects.

Damir: Alright, but we still have scripts, right? I mean, somewhere.

Todd: language, yeah, I kind of want to deprecate them in favor of like, a bit off topic here. But we can talk about that later.

Damir: I didn’t know if I should see LDR, so you know you could write a program and this program would be a transaction.

So usually, you call a specific method, you could write the whole program, and publish it as a transaction. so it’s like you published your whole program, and it does its job to enter like 100 addresses, and it will split your coin into like, 100 pieces, and you write it as code in Move, and it sends to this 100 addresses and it was like a really cool feature, which no one had, and now we don’t have to.

Todd: Yeah, I think it’s a bit tricky because the idea was the hope that you wouldn’t have to publish this code, but the script is still kind of has to live on chain somewhere, and that you need to be able to commit yourself to this execution and have some replay for it.

I think, maybe we’re kind of off topic at this point now. But yeah, that’s a feature of normal Move to where we are trading entry points to transactions a little bit differently as we move but we’re committing to these changes upstream and you know, I have the whole entry point story, has changed but recently for core Move not just for Sui.

Question #3: For Blockchain, how do smart contracts actually work?

Todd: Yeah, so it’s a little bit different for Sui as always saying you have these modules, and again, solidity is just like, I really hate the term talk smart contract for what it’s worth. I think it’s a stupid term and I think it’s really like marketing around the idea of programs, and that solidity it’s kind of like, I have a singleton object, or a singleton set of code that no one else can use. And here are some functions you can call into it, and the most similar it is any other kind of existing notion, at least as far as a Ethereum works, It’s kind of like an actor model. And a little way, it’s kind of like micro service model.

I just find the term smart contract a bit clever marketing. There’s nothing smart about it, there’s nothing really contracting about it. It’s just a program. That’s my own personal and I do know people like that term.

That being said, as far as modules are in Sui, I was saying that we set out to like, do something a little different Move, having these reusable modules of code, we do kind of publish them in a way that’s a bit more similar to smart contracts on Ethereum than in normal Move in Sui.

So if you want to write like a smart contract, you take a group of modules, and you publish them, in what we call a package in Sui, so you’d collect up your modules, you can link against other modules existing on chain, and then you publish those into your account. And you’ll get some ID for that.

So you have an object that contains, as I was saying, in Sui we have these objects for coins and other assets. And these objects don’t have to be just move values and move code. So you take all these things, and you package them up, and now you have an object representing a package. So that’s kind of how we’re structuring these things. But anyone can kind of call into it and link to it from their own code, you don’t have to do these delegate functions out to a different contract, that behaves a bit more similarly to how you might expect the code to work. If you’re writing like Python, or rust or Java.

There’s anything Damir, you want to say maybe you’re a bit more well versed in the Etherium space, if you want to maybe kind of go from there about how it’s similar and different.

Damir: Yeah, my theory of knowledge is outdated, very outdated in like years or something.

Todd: I mean, I don’t know if you wanna say anything else about the difference between a smart contract versus a Move package and Sui.

Damir: Yeah. But you got it right. I mean, usually we try to break code as generic as possible. So it is as reusable as possible, like if we have a coin module, which you can see, and we’re slowly shifting to the next question, which is about interfaces. If you look at our framework, you see that we have coin, but it’s like a generic point, which anyone can use to implement their coin.

So if you compare it to solidity, usually you publish like as Todd correctly mentioned that when you want to publish something like a smart contract, you usually need to implement everything from scratch. If you have like ERC 20 standard, you have this approve transfer et cetera, everything is described in an interface and you have to implement this interface and need to code everything yourself.

Uh, it is a good thing and a bad thing, is that while following this interface, you don’t necessarily have to implement them in a standard way. You can have the transfer method that just links all your money from you just Excel your money from you whenever you wanna transfer something, and that is a problem of interfaces in general. I love how Move addresses this problem, because we have generic implementations for any type T and if you look at our coin module to make another ERC 20, but I don’t like compare us to solidity, but anyway, if you wanna publish a coin or a token, you just publish like one line, which is like the name of your token, and it will be your ERC 20 coin on suing. And then you automatically get all the methods, like third main transfer, et cetera, and all the solutions we have in Move are pretty much generic and it improves called reusability. And that’s like one of the greatest features of language as well. And so even in our examples can be easily modified, if you have a sandwich example you will combine bread and butter or something. You can make a generic Combinator module, which will combine two modules somehow, I mean we can figure out the way to do it.

Question #4: Do you need interfaces and standards in Move like
RC 721 or the new one?

Damir: It is not necessary to have them and we don’t have interfaces. It is actually great things like Opensea exists. I mean, first of all, everything is an object, so if you just want everything to be transferable or spendable, et cetera, you just define your type of like a set of redefined abilities and you allow it to be transferred. And that’s it. So like my NFT, the me NFT and taught NFT, still different types, but they can share the same properties, and they implement the same interface.

So, if someone wants to build an Opensea, we don’t have to follow the same standard as RC 721, we can have like everything custom, custom metadata, custom waste to combine NFTs, custom waste to burn them. But the generic Opensea marketplace, we’ll be able to work with all of them if we just specify correct abilities on these types. So yeah, we don’t need interfaces.

Everything is generic almost by default and everything can be tuned like this slight modifications on how the type behaves, in how you define abilities for this type. They affect the way this type can be used.

Todd: So going even deeper into what Damir was saying, the interfaces are a crutch for the fact that you can’t really reuse code and there’s no way of kind of customizing existing code. So if you have like a token, you want to define it on solidity, it’s like, well, I can’t reuse the other existing token code. There’s no like token library. So you’re stuck trying to adhere to this interface. So the only solution and move the idea is that you write the coin type once and you’re done.

There’s like a coin module. And this describes the behavior of a coin. You have a coin asset, a type representing the coin, and then you have functionality over the coin. That’s gonna be the same for coins, where you have splitting and transferring and combining and withdrawing, et cetera.

So now when you want to come along and define your own token type, you can instantiate the coin type using generics and fill in the inner bits of the coin and saying, okay, I have a coin of Sui or a coin of Eth or a coin of Todd Nichols or whatever fantasy money you wanna make up on chain, you can just make a new module, make a new type, and then instant the coin type with your kind of new token type. And now it’s gonna work everywhere, once it works.

So if you have something like Opensea where you want to have transferring of these things, you can imagine having a generic type for coin or like you could have a generic wrapper for Opensea NFT. That way, the Opensea you can encapsulate your data in that type, and then it’d be good to go.

No, that’s kind of like the most straightforward connection to how things work in solidity, but we can do things a bit better here. I would say in Move, that’s kind of what Demir was talking about with these abilities for the types is that you can define your own type, your own NFT, and it actually doesn’t have to use these kind of rappers that I was just talking about. You can just do whatever you want and that if you have certain abilities, then the transferring of the Sui object is just gonna work generically across the board that we have this generalized transfer object, you can invoke a transaction, this transfer the object, and you’re done, but you don’t even need that, you don’t have to have this like public transfer, you can say, I want all code and all transfer to blow through my module. I want tight control of this behavior. And it’d still be easy enough for Opensea or someone of some other marketplace to expose this functionality. It might not be super pretty, but what you can do is you can look at the module and say, Hey, I have an object of this type. Let’s look for all the entry point function in this module that use that type. And you can say, okay, here are all the functions exposed in this module for this, for this type. And you can even say, oh, I actually want to call this other entry point and some other function. And I could imagine something like Opensea or some other Explorer, marketplace having a way of like saying, okay, I want go look at this module. And I want to use the object. I have stored in an exchange or something and I want to use it with this custom logic. So you don’t need to have just cause we don’t have interfaces. Doesn’t mean there’s like not a way of doing custom code too. I think is my point.

Damir: I can add to that. We actually have interfaces and we discovered them like a month ago. Yes, that is true, we still discover new patterns, we still discover new ways of expressing stuff. And if you go to our main branch on GitHub, you go to examples, there is this regulated coin example and it showcases that we kind of can have interfaces.

So, if you want to have this type, you need to implement a module that implements all of the methods of this type, I mean, it is technically an interface. It does allow you to implement your custom type custom interface. I mean, implement the interface, be usable, kind of as the type you are implementing. But on the other hand, you lose this property of like, uh, would I call it like generic ability? So, you can’t reuse this type, we have a regular coin example as a different coin because there are different types and so always better to go with generic, ready to go solutions. But if you wanna see how interfaces are implemented, then check out a regular coin example. I doubt anyone will ever use it, but maybe there will be someone.

Question #5: What do you think are the disadvantages of the Move programming language?

Todd: Yeah. I think we’re kind of hitting into some of them in an interesting way, I mean there’s disadvantages of things I’m unhappy about and like oh my God, why did we never get around to adding, you know, X, Y, Z feature? There’s still some basic stuff missing from the language or at least what I view is just, so I consider that at this advantage, most languages that you program with have some form of indirect calls, you have like some form of indirection. And if you’re programming in rust, you have a trait you’re programming in Java, you have like various interfaces or, other things you can do. And we just don’t have that. There’s no dynamic, dispatch is no indirect. Cause what you see is what you get in your module. And this is a feature in that, you get really strong guarantees about your code and you’re able to prove things about your code that you wouldn’t otherwise be able to prove formally. The downside is you have to think differently about how you’re laying out your code. You know, the coin module is great, but it’s just not, if you were working in another language, you just like probably wouldn’t set up the code that way.

So the, the amount of expressivity is similar, it’s just a bit different and the weight and the programming patterns that you have to use. So I would say that a disadvantage here is that in order to get kind of this power and these strong guarantees, you have to program a little bit differently. but I think about it, as kind of like driving on the other side of the road, Like in the UK, you drive on the left side of the road versus in the us for driving on the right, and they both work. It’s just that your muscle memory in terms driving is probably gonna be a little different and you’re gonna have moments where you’re gonna like freak out, like, oh my God, I’m driving on the wrong side of the road. but, you just kind of have to sit back and reassure yourself that you’re still gonna be able to get to where you want to go. You just have to be a little bit more careful. I don’t think a little bit differently than how you might have before.

Question #6: How would you implement a DNS in Move?

Damir: Our answer to that is that we will never implement it because we don’t need to. The actual problem that people usually ask is in places like solidity, because solidity is a reference smart contract language. It will change, but for now in solidity you can have like a hash map by central hash map that says this IP address is this domain name and vice versa and you can go to a single place and check a lot of data in the hash map. This was addressed as one of the main problems of Move.

You can’t have a centralized storage because it’s going to be super expensive. Move would lose all of its properties and become extremely slow. Any change that you do would affect the whole hash map. If you had a million records and you changed one or added one, you would have to rewrite 1,000,001 records again.

The DNS problem is something that we haven’t solved, but you can always find a way to implement it. Like Todd said, you need to change your mindset. You need to change your paradigm. You can always store a bunch of objects. It won’t be as programmable as you’re usually use to, like when you’re using a hashmap to create the result of an address or name of a website DNS.

It will be something different and might require more off chain tooling, but in the end you will have more efficient, more scalable result, but we try to not have huge centralized storages of data on the chain, because it is not effective.

Move makes most of the profits of its decentralization where all assets are spread on different addresses rather than putting it all together.

Todd: Most commonly the kind of questions we get are like, “I did this in solidity, how do I do this on Move?”. The answer is you don’t because you don’t need to. You should be laying out your code differently. You’re not centralizing all of the entries for your NFTs in a single map.

Instead you have individual NFT objects and the downstream effects of those decisions mean you just have to think a little bit differently about how you’re programming. For example, you should be programming on a kind of per asset style and not thinking about how would I do this with being able to view the entire world at once.

Question #7: What are the capabilities of privacy on Move? Are there limitations of privacy that you can enact on Move?

Damir: You wouldn’t from the language you would expect from the back end of like, because M produces by bytecode. This bytecode is something that can be produced in plain. It can be encoded somewhere else and you can use move by Mo VM inside some platform which would transform their code into a Zuki circuit, which no one will ever read if they don’t have the proven key and verifying key.

It’s not a problem of the language and shouldn’t be treated this way because we can always encode some data off chain and pass it into Move and then return the same encoded data. It will be private because no one knows the initial data.

On the other hand,if we just like take the move VM and like how private is bytecodes, it is less private than Solidity move bytecode is cleaner, it’s more decodable, it’s more usable and overall better if you’re a developer working on this bytecode. With solidity if you get a contract API, you usually cannot trade it because it’s encoded in a weird way.

You have lots of different directions of the compiler you don’t know what it was. Of course, there are probably some solidity compilers, but usually, you treat solidity by code as something like AFU, which you will never get. While with Move, you can also see it in our explorer, each program gets sort of depi I mean partially, you can always see the signatures, you can always see the types, so everything that happens with Move is transparent, you can check everything that’s going on, even the bite code.

Todd: Yeah. So let me hop in there, I think there’s just everything you talked about Damir.

You know, one of the goals for Move was set The VI code language, we have a strong guarantees at the VI code level, like there’s a type system for the VI code, but all of your asset and scarcity rules that ensure your objects or your types are being handled like they would for money, these guarantees are checked at the VI code level.

So, anyone could write a programming language or the bike code and get the same guarantees, or they’d be tied to having the same guarantees. And when we’re talking about being able to view everything and all the like signature functions that are stored on chain at the biker level, we refer to this as sort of a secure compilation pipeline so that when we’re thinking about Move programs as the source language and a different source language can make a different choice, but the language doesn’t add any abstractions that aren’t really present at the bike code layer.

Now, that’s not saying there aren’t like features that aren’t testing and there’s some annotations and the prover specifications, these only exist at the source language level, but when we’re talking about the signatures of functions, they’re exactly the same at the bike code level. And this is really important because it means that any of the guarantees you have at the source language are present at by care level. So if you’re trying to do something illegal or incorrect with the type, you wanna make sure that behavior is still present at the biker level, so you don’t gain expressivity by trying to interact with the bike code directly.

So that’s really what we’re talking about; secure compilation. That we’re having the same level of guarantees down the pipeline. I think that this is important to bring up when we’re talking about viewing code on-chain.

Question #8: So Move offers a unique feature for NFTs, but is there anything that it does in a unique way for DeFi that other languages don’t ?

Todd : I would say almost in a way that the type system doesn’t do anything unique for NFTs, it does something unique for assets. It just turns out that NFTs aren’t so interesting from a technical standpoint. They are really an instantiation of having rules the way things behave with real world items.

Damir : [Move] is super fast. It just provides security guarantees for everything you hold. It provides an inability for someone to seek your assets, to modify your state, to take something from you. So you are always safe if you own something. You have security guarantees, and the only problem you might face there is that the highest integer that we support is u128. We’re thinking of adding support for u120, u56, but that’s a huge question whether we actually need those or not. Apart from that, you get everything you need. You can work with math. You can work safely with assets, and lastly with Sui you can do this in a decentralized manner and with higher transaction volumes.

Thank you for tuning into our Move Programming Language AMA! If you have any feedback about how the AMAs were conducted, please don’t hesitate to reach out to social@mystenlabs.com with your input. We’re always looking to improve.

Learn more about Sui

Build with us!!

We’re excited about what the future unfolds and invite creators and builders to join us.

--

--