r55: Integrating RISC-V Smart Contracts with EVM on Ethereum

Summary
R55 is an experimental Ethereum Execution Environment designed to seamlessly integrate RISC-V smart contracts alongside traditional EVM smart contracts. This innovative approach allows for dual support over the same Ethereum state, enabling pure Rust smart contracts and opening the Ethereum development space to a vast Rust developer community. It leverages standard tooling like Rust, Cargo, and LLVM, simplifying development and integration.
Repository Info
Tags
Click on any tag to explore related repositories
Introduction
R55 is an experimental Ethereum Execution Environment that seamlessly integrates RISC-V smart contracts alongside traditional EVM smart contracts. This dual support operates over the same Ethereum state, allowing communication via ABI-encoded calls. On a high level, R55 enables the use of pure Rust smart contracts, opening the door for a vast Rust developer community to engage in Ethereum development with minimal barriers to entry and increasing language and compiler diversity. On a low level, RISC-V code allows for optimization opportunities distinct from the EVM, including the use of off-the-shelf ASICs, which can be particularly advantageous in specialized domains.
R55 relies on standard tooling that programmers are accustomed to, such as Rust, Cargo, and LLVM. This directly enables existing tooling like linters, static analyzers, testing, fuzzing, and formal verification tools to be applied to these smart contracts without extra development and research.
Installation
To get started with R55, you'll need to install some prerequisites.
macOS
brew tap riscv-software-src/riscv
brew install riscv-gnu-toolchain gettext
You'll also need to install Rust's RISC-V toolchain:
$ rustup install nightly-2024-02-01-x86_64-unknown-linux-gnu
Examples
R55 allows for pure and clean Rust smart contracts, enabling users to code in no_std Rust. The #[contract] macro is the only special treatment required, handling init code and function dispatching. Rust pub methods are exposed as public functions in the deployed contract, similar to Solidity's public functions.
Here's an example of a basic ERC20 token implementation:
#![no_std]
#![no_main]
use core::default::Default;
use contract_derive::contract;
use eth_riscv_runtime::types::Mapping;
use alloy_core::primitives::Address;
#[derive(Default)]
pub struct ERC20 {
balance: Mapping<Address, u64>,
}
#[contract]
impl ERC20 {
pub fn balance_of(&self, owner: Address) -> u64 {
self.balance.read(owner)
}
pub fn transfer(&self, from: Address, to: Address, value: u64) {
let from_balance = self.balance.read(from);
let to_balance = self.balance.read(to);
if from == to || from_balance < value {
revert();
}
self.balance.write(from, from_balance - value);
self.balance.write(to, to_balance + value);
}
pub fn mint(&self, to: Address, value: u64) {
let to_balance = self.balance.read(to);
self.balance.write(to, to_balance + value);
}
}
You can run the end-to-end test to see R55 in action, compiling and deploying the ERC20 contract to an internal revm-r55 instance:
$ cargo test --package r55 --test e2e -- erc20 --exact --show-output
Why use R55?
R55 offers several compelling reasons for adoption:
- Pure Rust Smart Contracts: Develop smart contracts using
no_stdRust, leveraging the language's safety and performance features. - Standard Tooling: Integrate seamlessly with existing Rust, Cargo, and LLVM tools, reducing the learning curve and enabling robust development practices.
- RISC-V Optimization: Explore new optimization opportunities distinct from the EVM, including the potential use of off-the-shelf ASICs for specialized tasks.
- EVM Compatibility: Maintain compatibility with the existing Ethereum state and EVM smart contracts, ensuring a smooth transition and interoperability.
- Client Integration: R55 is a fork of revm without API changes, allowing seamless integration into clients like Anvil/Reth for testnet/network deployment with RISC-V support.
Links
For more information and related projects, check out these links: