Traits or type-specific implementation in Move

Hello!

Do you have any plans or open proposals on traits/interfaces like in Rust? Will it be possible in future to do custom type/impl constraints (like or <T: copyable>)? Do you have decision on that or can we start a discussion?

Background:

I was thinking if I could implement custom ERC-20-like token in Move using Libra standard library. To do so I’d need to be able to create Libra::T resource - otherwise tokens would not be manageable via LibraAccount::Balance. As a design solution I was experimenting with possible register_token method in 0x0::LIbra which could have had type constraint of kind <T: Token> where Token is a system-defined trait.

Examples:

  public fun register_token<C: Token>(total_supply: u128, currency_code: vector<u8>, decimals: u8) {
      // it's a dirty and raw solution but catch the idea
      move_to_sender<Libra::T<C>>(Libra::T {
          value: total_supply
      });
      // and then register CurrencyInfo somehow
      // ...
  }

I was thinking if I could implement custom ERC-20-like token in Move using Libra standard library

A Libra::T<CoinType> resource is intended to be a generic representation of currency that supports adding custom tokens that share the same underlying logic.

  • Libra::CurrencyInfo<CoinType>.total_value is the equivalent of ERC20’s totalSupply
  • To create a custom coin, add a new module that declares a type to instantiate the CoinType type parameter. Here are two examples of this: Coin1 (a very simple custom coin) and LBR (a synthetic currency backed by an on-chain reserve of Coin1 and Coin2).
  • If a LibraAccount wishes to begin accepting a new currency MyCoin::T, it can call LibraAccount::add_currency<MyCoin::T> (which will publish a LibraAccount::Balance<MyCoin::T> under the sender’s account).

An important way that Libra differs from ERC20 is that it does not require (or allow) the custom token creator to reimplement logic that should be similar for all coins (e.g., computing the total value, joining/splitting coins, transfers,getting the value of a particular coin). The custom token implementer only needs to define additional constraints on minting (for example, it is possible to implement a currency that has a maximum total supply of 1000, or Bitcoin-like coin whose total supply increases in a predictable fashion over time) or burning (for example, it is possible to create a coin that can never be burned or a coin that costs 1 LBR to burn).

Do you have any plans or open proposals on traits/interfaces like in Rust? Will it be possible in future to do custom type/impl constraints (like or <T: copyable>)?

We are not currently planning to support traits or interfaces. We feel that dynamic dispatch is not an appropriate feature for a smart contract language (as we sometimes cheekily say: “in a world where code is law, interfaces are a crime”). Move’s ability to read/write global storage with a generic type parameter chosen at runtime (e.g., borrow_global<Libra::T<CoinType>>(addr) where CoinType is chosen at runtime) is quite powerful. Many patterns that would use an interface in a conventional language can also be implemented using this safer, more restrictive “storage polymorphism” (see LibraConfig for another example of this).

Hope this helps and let me know if you have more questions! Storage polymorphism and its associated design patterns are (in my view) subtle, but very flexible once you’ve gotten comfortable with it.

2 Likes

Thanks for quick response and for being so generous with your time!

A Libra::T<CoinType> resource is intended to be a generic representation of currency that supports adding custom tokens that share the same underlying logic.

I see. Yeah, Libra::T fits ERC20 requirements but it only allows registering new coins to association. How can one write his own token and register it in Libra ecosystem? Is it even possible? And if it’s currently not, are you going to let people create their own tokens? I mean apart from sender address check there’s somewhy additional check for AddCurrency privilege. Why do you need this check at all if there’s only one association address?

We are not currently planning to support traits or interfaces. We feel that dynamic dispatch is not an appropriate feature for a smart contract language (as we sometimes cheekily say: “in a world where code is law, interfaces are a crime”).

So true! I think I get the idea - never thought it has something to do with dynamic dispatch. Now it’s is clear.

1 Like

How can one write his own token and register it in Libra ecosystem? Is it even possible? And if it’s currently not, are you going to let people create their own tokens?

This will not be possible at launch because of the restrictions on publishing of third-party code without Association approval. But this may be relaxed in the longer term.

I mean apart from sender address check there’s somewhy additional check for AddCurrency privilege. Why do you need this check at all if there’s only one association address?

Good point; we are in the process of converting the code from using hardcoded address checks to permission checks like AddCurrency. We still have some hardcoded address checks that need to be killed.

1 Like