-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update
README.md
with crate info (#38)
Co-authored-by: John Adler <[email protected]>
- Loading branch information
Showing
3 changed files
with
85 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,14 @@ | ||
[package] | ||
name = "fuel-asm" | ||
description = "Defines all opcodes available in the FuelVM." | ||
version = "0.1.0" | ||
authors = ["Victor Lopez <[email protected]>"] | ||
categories = ["cryptography::cryptocurrencies", "data-structures", "parsing"] | ||
edition = "2021" | ||
repository = "https://github.com/FuelLabs/fuel-asm" | ||
homepage = "https://fuel.network/" | ||
keywords = ["blockchain", "cryptocurrencies", "fuel-vm", "vm"] | ||
categories = ["cryptography::cryptocurrencies", "data-structures", "parsing"] | ||
license = "Apache-2.0" | ||
repository = "https://github.com/FuelLabs/fuel-asm" | ||
description = "Defines all opcodes available in the FuelVM." | ||
|
||
[dependencies] | ||
fuel-types = { git = "ssh://[email protected]/FuelLabs/fuel-types.git", default-features = false } | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,79 @@ | ||
# fuel-asm | ||
# Fuel ASM | ||
|
||
[![build](https://github.com/FuelLabs/fuel-asm/actions/workflows/cargo_test.yml/badge.svg)](https://github.com/FuelLabs/fuel-asm/actions/workflows/cargo_test.yml) | ||
[![crates.io](https://img.shields.io/crates/v/fuel-asm?label=latest)](https://crates.io/crates/fuel-asm) | ||
[![docs](https://docs.rs/fuel-asm/badge.svg)](https://docs.rs/fuel-asm/) | ||
[![discord](https://img.shields.io/badge/chat%20on-discord-orange?&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/xfpK4Pe) | ||
|
||
Instruction set for the [FuelVM](https://github.com/FuelLabs/fuel-specs). | ||
|
||
## Compile features | ||
|
||
- `std`: Unless set, the crate will link to the core-crate instead of the std-crate. More info [here](https://docs.rust-embedded.org/book/intro/no-std.html). | ||
- `serde-types`: Add support for [serde](https://crates.io/crates/serde) for the types exposed by this crate. | ||
- `serde-types-minimal`: Add support for `no-std` [serde](https://crates.io/crates/serde) for the types exposed by this crate. | ||
|
||
## Example | ||
|
||
```rust | ||
use fuel_asm::*; | ||
use Opcode::*; | ||
|
||
// A sample program to perform ecrecover | ||
let program = vec![ | ||
MOVE(0x10, 0x01), // set r[0x10] := $one | ||
SLLI(0x20, 0x10, 5), // set r[0x20] := `r[0x10] << 5 == 32` | ||
SLLI(0x21, 0x10, 6), // set r[0x21] := `r[0x10] << 6 == 64` | ||
ALOC(0x21), // alloc `r[0x21] == 64` to the heap | ||
ADDI(0x10, 0x07, 1), // set r[0x10] := `$hp + 1` (allocated heap) | ||
MOVE(0x11, 0x04), // set r[0x11] := $ssp | ||
ADD(0x12, 0x04, 0x20), // set r[0x12] := `$ssp + r[0x20]` | ||
ECR(0x10, 0x11, 0x12), // recover public key in memory[r[0x10], 64] | ||
RET(0x01), // return `1` | ||
]; | ||
|
||
// Convert program to bytes representation | ||
let bytes: Vec<u8> = program.iter().copied().collect(); | ||
|
||
// A program can be reconstructed from an iterator of bytes | ||
let restored = Opcode::from_bytes_iter(bytes.iter().copied()); | ||
|
||
assert_eq!(program, restored); | ||
|
||
// Every instruction can be described as `u32` big-endian bytes | ||
let halfwords: Vec<u32> = program.iter().copied().map(u32::from).collect(); | ||
let bytes = halfwords.iter().copied().map(u32::to_be_bytes).flatten(); | ||
let restored = Opcode::from_bytes_iter(bytes); | ||
|
||
assert_eq!(program, restored); | ||
|
||
// We can also reconstruct the instructions individually | ||
let restored: Vec<Opcode> = halfwords.iter().copied().map(Opcode::from).collect(); | ||
|
||
assert_eq!(program, restored); | ||
|
||
// We have an unchecked variant for optimal performance | ||
let restored: Vec<Opcode> = halfwords | ||
.iter() | ||
.copied() | ||
.map(|w| unsafe { Opcode::from_bytes_unchecked(&w.to_be_bytes()) }) | ||
.collect(); | ||
|
||
assert_eq!(program, restored); | ||
|
||
// Finally, we have [`Instruction`] to allow optimal runtime parsing of the components of the | ||
// opcode | ||
// | ||
// `Opcode` itself is only but an abstraction/helper to facilitate visualization, but the VM is | ||
// expected to use raw instructions | ||
let instrs: Vec<Instruction> = program.iter().copied().map(Instruction::from).collect(); | ||
let restored: Vec<Opcode> = instrs.iter().copied().map(Opcode::from).collect(); | ||
|
||
assert_eq!(program, restored); | ||
|
||
// An instruction is composed by the opcode representation registers Id and immediate values | ||
assert_eq!(instrs[1].op(), OpcodeRepr::SLLI as u8); | ||
assert_eq!(instrs[1].ra(), 0x20); | ||
assert_eq!(instrs[1].rb(), 0x10); | ||
assert_eq!(instrs[1].imm12(), 5); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters