Skip to content

Commit

Permalink
Initial execution loop with 3 opcodes implemented, README setup.
Browse files Browse the repository at this point in the history
  • Loading branch information
b-j-roberts committed Jul 24, 2024
1 parent 4cbe8d2 commit a4853f7
Show file tree
Hide file tree
Showing 21 changed files with 778 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @b-j-roberts
7 changes: 7 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!-- enter the gh issue after hash -->

- [ ] issue #
- [ ] follows contribution [guide](https://github.com/keep-starknet-strange/shinigami/blob/main/CONTRIBUTING.md)
- [ ] code change includes tests

<!-- PR description below -->
4 changes: 4 additions & 0 deletions .github/linter/base_style.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
all
# lame rules
exclude_rule 'MD002'
exclude_rule 'MD041'
12 changes: 12 additions & 0 deletions .github/linter/readme_style.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
all
# allow inline HTML for README fmt
exclude_rule 'MD033'
# badges trigger rule
exclude_rule 'MD034'
# README img serves as 'First Header'
exclude_rule 'MD002'
exclude_rule 'MD041'
# TODO: disable/enable not working for all-contribs
exclude_rule 'MD013'
# Allow no endline at the end
exclude_rule 'MD047'
18 changes: 18 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: build

on:
workflow_dispatch:
push:
branches:
- main
pull_request:
permissions: read-all

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: asdf-vm/actions/install@v3
- run: scarb fmt --check
- run: scarb build
27 changes: 27 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: check

on:
workflow_dispatch:
push:
branches:
- main
pull_request:
permissions: read-all

jobs:
markdown:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
sudo gem install mdl
mdl -s .github/linter/readme_style.rb README.md
mdl -s .github/linter/base_style.rb .github
mdl -s .github/linter/book_style.rb book
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: asdf-vm/actions/install@v3
- run: scarb test
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Sys files
**/.DS_Store

# Scarb and Starknet Foundry
**/target
**/.snfoundry_cache/

# Starkli
**/account.json
**/keystore.json

# All Contributors CLI
/package.json
/yarn.lock
node_modules/

# Development
**/TODO
65 changes: 65 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
## 🛠️ Contributing to shinigami 🛠️

Welcome, contributing to `shinigami` is easy!

1. Submit or comment your intent on an issue
1. We will try to respond quickly
1. Fork this repo
1. Submit your PR against `main`
1. Address PR Reviews

### Issue

Project tracking is done via GitHub [issues](https://github.com/keep-starknet-strange/shinigami/issues)
First look at open issues to see if your request is already submitted.
If it is comment on the issue requesting assignment, if not open an issue.

We use 3 issue labels for development:

- `feat` -> suggest new feature
- `bug` -> create a reproducible bug report
- `dev` -> non-functional repository changes

These labels are used as prefixes as follows for `issue`, `branch name`, `pr title`:

- `[feat]` -> `feat/{issue #}-{issue name}` -> `feat:`
- `[bug]` -> `bug/{issue #}-{issue name}` -> `bug:`
- `[dev]` -> `dev/{issue #}-{issue name}` -> `dev:`

#### TODO

If your PR includes a `TODO` comment please open an issue and comment the relevant
code with `TODO(#ISSUE_NUM):`.

### Submit PR

Ensure your code is well formatted, well tested and well documented. A core contributor
will review your work. Address changes, ensure ci passes,
and voilà you're a `shinigami` contributor.

Markdown [linter](https://github.com/markdownlint/markdownlint?tab=readme-ov-file#markdown-lint-tool):

```bash
mdl -s .github/linter/readme_style.rb README.md
```

Scarb linter:

```bash
scarb fmt
```

### Additional Resources

- [Cairo Book](https://book.cairo-lang.org/)
- [Starknet Book](https://book.starknet.io/)
- [Starknet Foundry Book](https://foundry-rs.github.io/starknet-foundry/)
- [Starknet By Example](https://starknet-by-example.voyager.online/)
- [Starkli Book](https://book.starkli.rs/)
- [Bitcoin Wiki](https://en.bitcoin.it/wiki/Script)
- [Golang Bitcoin Implementation](https://github.com/btcsuite/btcd)
- [Syncing a Fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork)

##

Thank you for your contribution!
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<div align="center">
<img src="resources/shinigami-logo/shinigami.png" alt="shinigami-logo" height="300"/>

***Bitcoin Script VM in Cairo***

[![Check Workflow Status](https://github.com/keep-starknet-strange/shinigami/actions/workflows/check.yml/badge.svg)](https://github.com/keep-starknet-strange/shinigami/actions/workflows/check.yml)
[![Build Workflow Status](https://github.com/keep-starknet-strange/shinigami/actions/workflows/build.yml/badge.svg)](https://github.com/keep-starknet-strange/shinigami/actions/workflows/build.yml)

[![Exploration_Team](https://img.shields.io/badge/Exploration_Team-29296E.svg?&style=for-the-badge&logo=data:image/svg%2bxml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIGlkPSJhIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxODEgMTgxIj48ZGVmcz48c3R5bGU+LmJ7ZmlsbDojZmZmO308L3N0eWxlPjwvZGVmcz48cGF0aCBjbGFzcz0iYiIgZD0iTTE3Ni43Niw4OC4xOGwtMzYtMzcuNDNjLTEuMzMtMS40OC0zLjQxLTIuMDQtNS4zMS0xLjQybC0xMC42MiwyLjk4LTEyLjk1LDMuNjNoLjc4YzUuMTQtNC41Nyw5LjktOS41NSwxNC4yNS0xNC44OSwxLjY4LTEuNjgsMS44MS0yLjcyLDAtNC4yN0w5Mi40NSwuNzZxLTEuOTQtMS4wNC00LjAxLC4xM2MtMTIuMDQsMTIuNDMtMjMuODMsMjQuNzQtMzYsMzcuNjktMS4yLDEuNDUtMS41LDMuNDQtLjc4LDUuMThsNC4yNywxNi41OGMwLDIuNzIsMS40Miw1LjU3LDIuMDcsOC4yOS00LjczLTUuNjEtOS43NC0xMC45Ny0xNS4wMi0xNi4wNi0xLjY4LTEuODEtMi41OS0xLjgxLTQuNCwwTDQuMzksODguMDVjLTEuNjgsMi4zMy0xLjgxLDIuMzMsMCw0LjUzbDM1Ljg3LDM3LjNjMS4zNiwxLjUzLDMuNSwyLjEsNS40NCwxLjQybDExLjQtMy4xMSwxMi45NS0zLjYzdi45MWMtNS4yOSw0LjE3LTEwLjIyLDguNzYtMTQuNzYsMTMuNzNxLTMuNjMsMi45OC0uNzgsNS4zMWwzMy40MSwzNC44NGMyLjIsMi4yLDIuOTgsMi4yLDUuMTgsMGwzNS40OC0zNy4xN2MxLjU5LTEuMzgsMi4xNi0zLjYsMS40Mi01LjU3LTEuNjgtNi4wOS0zLjI0LTEyLjMtNC43OS0xOC4zOS0uNzQtMi4yNy0xLjIyLTQuNjItMS40Mi02Ljk5LDQuMyw1LjkzLDkuMDcsMTEuNTIsMTQuMjUsMTYuNzEsMS42OCwxLjY4LDIuNzIsMS42OCw0LjQsMGwzNC4zMi0zNS43NHExLjU1LTEuODEsMC00LjAxWm0tNzIuMjYsMTUuMTVjLTMuMTEtLjc4LTYuMDktMS41NS05LjE5LTIuNTktMS43OC0uMzQtMy42MSwuMy00Ljc5LDEuNjhsLTEyLjk1LDEzLjg2Yy0uNzYsLjg1LTEuNDUsMS43Ni0yLjA3LDIuNzJoLS42NWMxLjMtNS4zMSwyLjcyLTEwLjYyLDQuMDEtMTUuOGwxLjY4LTYuNzNjLjg0LTIuMTgsLjE1LTQuNjUtMS42OC02LjA5bC0xMi45NS0xNC4xMmMtLjY0LS40NS0xLjE0LTEuMDgtMS40Mi0xLjgxbDE5LjA0LDUuMTgsMi41OSwuNzhjMi4wNCwuNzYsNC4zMywuMTQsNS43LTEuNTVsMTIuOTUtMTQuMzhzLjc4LTEuMDQsMS42OC0xLjE3Yy0xLjgxLDYuNi0yLjk4LDE0LjEyLTUuNDQsMjAuNDYtMS4wOCwyLjk2LS4wOCw2LjI4LDIuNDYsOC4xNiw0LjI3LDQuMTQsOC4yOSw4LjU1LDEyLjk1LDEyLjk1LDAsMCwxLjMsLjkxLDEuNDIsMi4wN2wtMTMuMzQtMy42M1oiLz48L3N2Zz4=)](https://github.com/keep-starknet-strange)

</div>

## Overview

`shinigami` is a library enabling Bitcoin Script VM execution in Cairo, thus allowing the generation of STARK proofs of generic Bitcoin Script computation.

Key features :
- Bitcoin script interpretation and execution
- Easily configurable VM ( enable different op-codes )

### Running

```bash
scarb cairo-run --available-gas=200000000
```

This will run the provided Bitcoin Script in Cairo.

### Building

```bash
scarb build
```

This will compile all the components.

### Testing

```bash
scarb test
```

This will run the test-suite for all op-codes, integration, and test Bitcoin Scripts.

## References

- [Bitcoin Script Wiki](https://en.bitcoin.it/wiki/Script)
- [Telegram]()
- [OnlyDust]()

## Contributors ✨

Thanks goes to these wonderful people. Follow the [contributors guide](https://github.com/keep-starknet-strange/art-peace/blob/main/CONTRIBUTING.md) if you'd like to take part.
6 changes: 6 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Code generated by scarb DO NOT EDIT.
version = 1

[[package]]
name = "shinigami"
version = "0.1.0"
8 changes: 8 additions & 0 deletions Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "shinigami"
version = "0.1.0"
edition = "2023_11"

# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html

[dependencies]
13 changes: 13 additions & 0 deletions resources/how-to-add-an-opcode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## How to add an opcode to "Shinigami"

1. Understand how the opcode works by looking at documentation:
- [Bitcoin Script Wiki](https://en.bitcoin.it/wiki/Script)
- [Reference implementation in BTCD](https://github.com/btcsuite/btcd/blob/b161cd6a199b4e35acec66afc5aad221f05fe1e3/txscript/opcode.go#L312)
- In BTCD find the function that matches the last element in `opcodeArray` for the specified opcode, that will be the reference implementation.
1. Add the Opcode to `src/opcodes/opcodes.cairo`
- Add the Opcode byte const like `pub const OP_ADD: u8 = 147;`
- Create the function implementing the opcode like `fn opcode_add(ref engine: Engine) {`
- Add the function to the `execute` method like `147 => opcode_add(ref engine),`
1. Add the Opcode to the compiler dict at `src/compiler.cairo` like `opcodes.insert('OP_ADD', Opcode::OP_ADD);`.
1. Create a test for your opcode at `src/opcodes/tests/test_opcodes.cairo` and ensure all the logic works as expected.
1. Create a PR, ensure CI passes, and await review.
Binary file added resources/shinigami-logo/shinigami.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 73 additions & 0 deletions src/compiler.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use shinigami::opcodes::Opcode;

// Compiler that takes a Bitcoin Script program and compiles it into a bytecode
#[derive(Destruct)]
pub struct Compiler {
// Dict containing opcode names to their bytecode representation
opcodes: Felt252Dict<u8>
}

pub trait CompilerTrait {
// Create a compiler, initializing the opcode dict
fn new() -> Compiler;
// Compiles a program like "OP_1 OP_2 OP_ADD" into a bytecode run by the Engine.
fn compile(self: Compiler, script: ByteArray) -> ByteArray;
}

pub impl CompilerTraitImpl of CompilerTrait {
fn new() -> Compiler {
let mut opcodes = Default::default();
// Add the opcodes to the dict
opcodes.insert('OP_0', Opcode::OP_0);
opcodes.insert('OP_1', Opcode::OP_1);
opcodes.insert('OP_ADD', Opcode::OP_ADD);
Compiler { opcodes }
}

// TODO: Why self is mutable?
fn compile(mut self: Compiler, script: ByteArray) -> ByteArray {
let mut bytecode = "";
let seperator = ' ';
let byte_shift = 256;
let max_word_size = 31;
let mut current: felt252 = '';
let mut i = 0;
let mut word_len = 0;
let mut current_word: felt252 = '';
while i < script.len() {
let char = script[i].into();
if char == seperator {
let opcode = self.opcodes.get(current);
current_word = current_word * byte_shift + opcode.into();
word_len += 1;
if word_len >= max_word_size {
// Add the current word to the bytecode representation
bytecode.append_word(current_word, max_word_size);
word_len = 0;
}
current = '';
} else {
// Add the char to the bytecode representation
current = current * byte_shift + char;
}
i += 1;
};
// Handle the last opcode
if current != '' {
let opcode = self.opcodes.get(current);
current_word = current_word * byte_shift + opcode.into();
word_len += 1;
if word_len >= max_word_size {
// Add the current word to the bytecode representation
bytecode.append_word(current_word, max_word_size);
word_len = 0;
}
}
if word_len > 0 {
// Add the current word to the bytecode representation
bytecode.append_word(current_word, word_len);
}

bytecode
}
}
Loading

0 comments on commit a4853f7

Please sign in to comment.