RISC-V, WASM, RUST, and U

Beyond this gem of obviousness on the long term prospects of Rust as a widely adopted and practiced smart contract language, I’m curious where the IC comes down on this RISC-V issue. I’m guessing that Gen-2 hardware doesn’t have RISC-V chips in them, but in some far flung future, how compatible is WASM with RISC-V?

6 Likes

Woah, so you hate NFTs and now Rust too?

Rust may be unsuitable for EVM-based smart contracts, I have no idea. Rust on the IC is perfect for this sort of thing.

This is without using a data model / query language crate like mimic.

use candid::{CandidType, Deserialize, Nat};
use ic_cdk::api::{caller, time};
use ic_cdk_macros::*;
use std::cell::RefCell;

#[derive(CandidType, Deserialize, Clone, Debug)]
struct SaleState {
    sold: u64,
    m: u64,
}

thread_local! {
    static STATE: RefCell<SaleState> = RefCell::new(SaleState {
        sold: 0,
        m: 0,
    });
}

#[init]
fn init(m: u64) {
    STATE.with(|s| s.borrow_mut().m = m);
}

#[query]
fn get_state() -> SaleState {
    STATE.with(|s| s.borrow().clone())
}

#[update]
fn buy_sock() -> Result<Nat, String> {
    let price = STATE.with(|s| {
        let mut state = s.borrow_mut();
        if state.sold >= 500 {
            return Err("All socks have been sold.".to_string());
        }

        let n = state.sold;
        let m = state.m;

        let price = calculate_price(m, n)?;
        state.sold += 1;
        Ok(price)
    })?;

    // NOTE: You would implement actual ICP/cycle collection here
    // For now, we just simulate a payment required
    Ok(price.into())
}

fn calculate_price(m: u64, n: u64) -> Result<u64, String> {
    if n >= 500 {
        return Err("Sold out.".to_string());
    }

    let a = m.checked_div(500 - n).ok_or("Division error")?;
    let b = m.checked_div(501 - n).ok_or("Division error")?;
    let price = a.checked_sub(b).ok_or("Subtraction error")?;
    Ok(price)
}

4 Likes

Hi @skilesare !
The choice of AMD CPUs for the short-to-medium term isn’t about WASM but mostly about SEV-SNP tech, which is currently exclusive to AMD CPUs.

We are watching with interest the groundwork done by the teams behind Keystone Enclave, Sanctum, and CoVE in the RISC-V space, but they seem to be in much earlier stages than SEV-SNP.

So, we don’t rule out the switch to RISC-V in the long term, provided the availability of products with these chips, support in the server platforms, a reasonable price-performance ratio, and the ability to run confidential VM computing inside. Still, we think it will be unlikely to happen in the next five years.

7 Likes

The push to replace the EVM with RISC-V is largely based on the fact that most zkVMs today use RISC-V as a backend. But even within the unique constraints that they have.. its not a good idea.

Why?

  1. ZK efficiency doesn’t require RISC-V
    RISC-V is simple, yes — but not optimized for zero-knowledge. Custom ZK-friendly ISAs can outperform it significantly. There’s nothing inherently ZK-native about RISC-V other than being “not as bad as EVM.” Smaller opcode amount compared to WASM … but this also does not realy matter as a’la’carte proving schemes exist.

  2. General-purpose ≠ optimal
    RISC-V, like WASM, is a general-purpose ISA. But while WASM has seen massive adoption across browsers, VMs, and languages (e.g., Rust → WASM), RISC-V doesn’t yet have equivalent mainstream traction for blockchain execution. Why switch from one general-purpose standard to another?

  3. WASM already won the tooling war
    The Internet Computer runs WASM natively and supports developer-friendly languages like Rust, Motoko, and C++. Toolchains, debuggers, interpreters, and formal analysis tools for WASM are mature. RISC-V lags in this area for smart contract devs.

  4. WebAssembly is portable, secure, and battle-tested
    WASM was built with sandboxing, determinism, and portability in mind — ideal for blockchain environments. It’s already run at scale (across all browsers), while RISC-V is still working toward this level of runtime hardening.

  5. Developer experience matters
    Rust → WASM is a first-class citizen today. The same isn’t true for Rust → RISC-V, especially in blockchain contexts. If you care about smart contract portability, security audits, and language support, WASM is ahead.

We have a SOTA zkWASM here →

Major upgrades are coming to once again 100x prover speed, for the IC, browsers, and more.

3 Likes

Oh, I don’t hate RUST. In fact, all the smartest programs I know swear by it and love it. Those folks are like geniuses level and top 5% of programmers I know. Genius level folks and people I admire. So there is obviously some magic there.

But it seems to have a negative viral coefficient. It is ugly as sin and bottom 95% programmers bounce upon first reading. It also seems to be very proprietary in the sense that only the author can really tell wtf the intent was. It scream “trust me bro…move along…you are not smart enough to be here.” It seems to have a strong community loyal devs but doesn’t ever develop community on (smart contract)projects using it.

If one were attempting to attract a world following building a new world computer one would want to attract a large following of developers that stick to a language to the effect of growing developer proficiencies. Rust seem to attract those that have already arrived and leaves everyone else standing outside.

A theoretical most proficient language in the world that can’t keep sub-grade devs long enough to make them world class won’t win. I mean we live in a world where JavaScript ruled for decades despite being reviled by anyone who knew anything about how programming was supposed to work.

Your mimic looks super powerful and I bet it is memory efficient as hell, but even your basic example burns your eyes if you’ve come from some thing like Linq in C# or some of the more basic and straightforward ORMs in the js/ts world. I’d imagine you’ll have great success with it and at devs that you pay to use it. I’m not long on the open source world picking it up and running with it(I’d love to be wrong but I’ve become cynical…the best tech doesn’t win even if I really really want it to).

Rust is what you would pick if you had unlimited funds, were building a closed source project, and have an awesome HR department that can weed through the chaff and find the devs you need to be successful.

If you are on a shoe string and need to have community take up and contribution to even get your project across the finish line then you probably(almost certainly) want to look elsewhere.

We aren’t exactly swimming in options. Solidity relies on some underlying assembly like data structures poking through as necessary too often, but is infinitely more readable. Motoko is super young and needs some serious progress(I’m looking at you sub actor pattern) to be easily digestible. Python’s batteries included often makes it a bit perilous for smart contracts but is super readable. Typescript is still too javascripty but has a billionty developers.

I have no solution here, but the empirical evidence of four years of RUST being the mostly only viable option in a smart contract community seems to be damning.

(Note 1: If the uber tech in you is internally screaming about how superior Rust is in category x(memory security, efficiency, etc, etc), I see you and you are not wrong…your language syntax just sucks upon first impressions which is often the only impression you get.)

(Note 2: perhaps this is all irrelevant and in a year or two the world will be vibe coding RUST with no issues whatsoever and no one will ever need/want/have to read the code, but that feels like it won’t be true.)

4 Likes

This is actually a fair take.

From someone who’s doubled down on everything Rust :slight_smile:

1 Like

@skilesare

Im trying to learn rust but like you say it “burns my eyes”

Id rather write in pure C to be honest, or motoko.

2 Likes

As someone who considers the ease of understanding source code to be one of the advantages of Rust, I found this to be an interesting opinion :eyes:

2 Likes

Congrats youre top 5% :clap:

THIS

This is why developers will increasingly choose Rust in spite of the “unreadabilty” and the “learning curve”.

Every garbage collected language, be it Motoko or your favourite language, JavaScript or Python, has this problem.

Because, in large complex codebases, no matter how proficient of a developer you are, you’ll end up mutating something that will change behaviour in a different value owing to its shared dependency on a particular value.
Rust makes this near impossible unless you turn off the default compiler behaviour. It makes you voluntarily make these decisions in limited scopes that you explicitly have to opt in to

Please note that the asker here is also a veteran dev who’s written a significant amount of canisters. Most well known for the stable structure libraries and currently maintaining a slew of products like Burn the PoW token and MSQ the wallet.

While the question I asked in the original thread may sound like I’m not pleased with the fact that Motoko is pass-by-reference, I’m actually choosing Motoko for out next project exactly because of this.

Rust is fire, yes. But in this particular project of ours there is a lot of intervined data structures which have to point to each other and have to be stored in stable memory. While it is possible in Rust, it would add another thing to worry about. Plus the stable-structures lib memory allocator is not suited for this kind of stuff well.

At this point, I’m too tired of writing all the boilerplate like thread_local! {....} or making sure that buffers are encoded with serde_bytes. Yes, rust gives you more performance. But honestly, since the DTS was implemented, I believe that if you’re hitting a cycle limit:

  • your architecture won’t work well under load even on a centralized server and you should look for a better one in terms of O-complexity;
  • or you shouldn’t implement this software on the IC at all (like LLMs people try to put into canisters - I understand the need, but IC nodes’ specs are simply not suited for that).
2 Likes

This seems like an architectural issue. If you want two copies, clone the object. If you want one then store the ID and operate through a layer that takes the ID.

My understanding of the magic of rust is that it forces the dev to think about memory, object ownership, etc. which can be an accelerant for simplifying and writing highly responsible code. I think that is great, but also not what most devs ‘want’ to do.

In Adam’s example you have:

Line 1: Serialization
giphy
Line 4: RefCell(I’m guessing memory by reference?)
giphy
Line 6: Serialization and Cloning
giphy
Line 12: Threads
giphy
:grimacing: :joy:

…and you’ve lost them. Again…you’re not wrong…maybe we all get to RUST when we get serious enough, but I’ve seen enough good stuff get done without having to think about threads, memory management and serialization to think it is possible.

Maybe a dumb question: Is there a sugary rust that gets rid of some of the stuff that the IC makes irrelevant anyway? For example, what does thread_local do anyway when you have a single-threaded platform? Shouldn’t it be assumed?

1 Like

thread_local allows you to test the code, since cargo’s test runners execute in parallel via multiple threads.

Also, the Rust compiler doesn’t know about the IC.

What you’re compiling to are targets.

In this case the target that the IC accepts and hence declared in the Rust compiler toolchain is wasm32-unknown-unknown triplet
Here are other triplets supported by the compiler:

Since the compiler only knows that it’s for wasm32 and nothing else, it doesn’t know explicitly whether the built binary executable would execute in a single threaded or multi threaded runtime.

Now if only the IC targeted something like wasm32-wasip2, I imagine we could do away with that ugliness since you don’t have to deal with threading and have more constraints to enforce and just be able work with top level variables like you do with Motoko.

You’ll probably have better ergonomics than Motoko (probably) because then since it’s standards compliant and supports sys calls to native storage, you could have DB libraries working, at least the file based ones out of the box

^ Some wishful thinking above.