Git Product home page Git Product logo

sigma-rust's Introduction

Coverage Status

Rust implementation of ErgoScript cryptocurrency scripting language.

See Architecture for high-level overview.

Crates

ergo-lib Latest Version Documentation

Overarching crate exposing wallet-related features: chain types (transactions, boxes, etc.), JSON serialization, box selection for tx inputs, tx builder and signing. Exports other crates API, probably the only crate you'd need to import.

ergotree-interpreter Latest Version Documentation

ErgoTree interpreter

ergotree-ir Latest Version Documentation

ErgoTree IR and serialization.

ergoscript-compiler Latest Version Documentation

ErgoScript compiler.

sigma-ser Latest Version Documentation

Ergo binary serialization primitives.

Bindings:

Changelog

See CHANGELOG.md.

Usage Examples

To get better understanding on how to use it in your project check out how its being used in the following projects:

Rust:

TS/JS:

Examples:

Also take a look at tests where various usage scenarios were implemented.

Contributing

See Contributing guide.

Feel free to join the Ergo Discord and ask questions on #sigma-rust channel.

sigma-rust's People

Contributors

abchrisxyz avatar alesfatalis avatar aostiles avatar apextheory avatar fitzoreilly avatar gagarin55 avatar gbrew avatar greenhat avatar hanbu97 avatar jasondavies avatar jerry-best avatar kettlebell avatar mkermani144 avatar oskin1 avatar p-gentili avatar qy3u avatar robkorn avatar rooooooooob avatar ross-weir avatar sahandzou avatar sebastiengllmt avatar sethdusek avatar shimuuar avatar techraed avatar venoox avatar yazgoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sigma-rust's Issues

Add missing ErgoTree IR nodes (serialization, evaluation)

List if missing nodes is in ergotree-ir/README.md

Create new struct in a separate module(file) in mir module and add it to Expr enum.

Serialization

  • Implement SigmaSerializable trait and add node's op code in serialization::expr;
  • Implement Arbitrary trait and add serialization roundtrip PBT test for this node;

Evaluation

  • Implement Evaluable trait in ergotree-interpreter crate;
  • Add evaluation tests;

Checkout implemented IR nodes (Fold, ByIndex) for implementation details.

readme updates

It would be great to put readme for project setup and project use.

ErgoTree for P2PK contract serialized into wrong bytes

Following peace of code

    let encoder = sigma_tree::chain::AddressEncoder::new(sigma_tree::chain::NetworkPrefix::Mainnet);
    let address = encoder.parse_address_from_str("9hzP24a2q8KLPVCUk7gdMDXYc7vinmGuxmLp5KU7k9UwptgYBYV").unwrap();

    let contract = sigma_tree::chain::Contract::pay_to_address(address).unwrap();
   let bytes = &contract.get_ergo_tree().sigma_serialise_bytes();

returns bytes

[
    0,  0,   8, 205,   3,  51,  44, 148,  61,
  231, 78, 149,   5,  42,  24, 133, 168, 248,
   27, 78, 229, 222, 113,  89, 161, 129,  66,
  225, 90,  46, 207,  24, 205,  23,   3, 104,
  219
]

It seems that first zero byte is redundant

C bindings and Swift wrapper for iOS

The following workflow should be supported:

  1. Create a box (with P2PK contract);
  2. Create a transaction;
  3. Specify transaction inputs;
  4. Sign created transaction;
  5. Serialize the signed transaction to JSON.

[5000 SigmaUSD] C + Swift(iOS) bindings

Scope

Implement an API feature-wise on par with Wasm bindings (ergo-lib-wasm). Basically an API that a wallet would need to be able to send and receive coins and tokens including input box selection, output box creation and transaction building and signing.

Architecture

The core part is the common/shared source code with JNI (ergo-lib-jni) that should be implemented in ergo-lib-c-core crate.
The generic C bindings should be implemented in ergo-lib-c which should be used in Swift wrapper that should be implemented in ergo-lib-ios.

C

The main idea is to pass Rust types wrapped in opaque pointers and expose functions to manipulate them on C side.
The crucial part is to free resources on the same side(usually Rust) where they were allocated. For this we need to expose a separate function for every "resource-producing" function that frees a resource passed from C. In case of Address see address_from_testnet and address_delete.

Use the already implemented Address type as an example.

Swift

Wraps functions from ergo-lib-c in classes for resource management and exposes methods converting to/from Swift types where necessary.

Types

Using Wasm bindings as a reference we need the following types(with methods) implemented. For implmentation details see Wasm types and their methods in ergo-lib-wasm. Some method names are adopted for C types. See implemented Address type

Wallet:
from_secrets
sign_transaction

SecretKey:
dlog_from_bytes
to_bytes

ErgoStateContext:
new(from PreHeader)

PreHeader:
from_block_header

BlockHeader:
from_json

BlockHeaders:
from_json

UnsignedTransaction:
id
inputs
data_inputs
output_candidates
to_json
from_json

ErgoBox:
new
box_id
creation_height
tokens
ergo_tree
value
register_value
to_json
from_json

ErgoBoxCandidate:
creation_height
tokens
ergo_tree
value
register_value

Token:
new
id
amount

TokenId:
from_box_id
from_str
to_str

TokenAmount:
from_int64_t
as_int64_t

BoxValue:
from_int64_t
as_int64_t

Transaction:
id
to_json
from_json
inputs
data_inputs
output_candidates
outputs

DataInput:
new
box_id

TxBuilder:
new
set_data_inputs
build
box_selection
data_inputs
output_candidates
current_height
fee_amount
change_address
min_change_value

ErgoBoxCandidateBuilder:
new
set_min_box_value_per_byte
min_box_value_per_byte
set_value
value
calc_box_size_bytes
calc_min_box_value
set_register_value
register_value
delete_register_value
mint_token
add_token
build

BoxSelection:
new
boxes
change

SimpleBoxSelector:
select

ErgoBoxAssetsData:
new
value
tokens

Collections

The following types represent a simple wrapper for Vec. Feel free to explore the idea to use the single type (pointer+size) since Rust arrays and slices have the same representation in C (arrays).

ErgoBoxCandidates;
Tokens;
DataInputs;
ErgoBoxAssetsDataList;
SecretKeys;
ErgoBoxes (instead of UnspentBoxes, OutputBoxes, DataInputBoxes)

All of them should implement the following methods:
new
len
get
add

The ErgoBoxes type should implement from_boxes_json method (see Wasm).

Add tests for PeekableReader

Implementation pulled from https://github.com/C4K3/peekable-reader-rs/blob/master/src/lib.rs
in #24
Check the tests there and implement/move the relevant tests.

impl<R: Read> Peekable for PeekableReader<R> {
/// Returns the `io::Result` which the Reader will return on the next
/// `get_byte` call.
///
/// If the `io::Result` is indeed an `io::Error`, the error will be returned
/// for any subsequent read operation invoked upon the `Read`er.
fn peek_u8(&mut self) -> Result<u8, &Error> {
// Return either the currently cached peeked byte or obtain a new one
// from the underlying reader.
match self.peeked_result {
Some(Ok(x)) => Ok(x),
Some(Err(ref e)) => Err(e),
None => {
// First get the result of the read from the underlying reader
let mut tmp: [u8; 1] = [0];
self.peeked_result = match self.inner.read_exact(&mut tmp) {
Ok(()) => Some(Ok(tmp[0])),
Err(e) => Some(Err(e)),
};
// Now just return that
let tmp: Result<u8, &Error> = match self.peeked_result {
Some(Ok(x)) => Ok(x),
Some(Err(ref e)) => Err(e),
None => unreachable!(),
};
tmp
}
}
}
}
impl<R: Read> PeekableReader<R> {
/// Initializes a new `PeekableReader` which wraps the given underlying
/// reader.
pub fn new(reader: R) -> PeekableReader<R> {
PeekableReader {
inner: reader,
peeked_result: None,
}
}
}
impl<R: Read> Read for PeekableReader<R> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
if buf.len() == 0 {
return Ok(0);
}
// First, put the byte that was read off the underlying reader in a
// (possible) previous peek operation (if such a byte is indeed cached)
let mut tmp = None;
swap(&mut tmp, &mut self.peeked_result);
let offset = match tmp {
Some(Err(e)) => {
return Err(e);
}
Some(Ok(b)) => {
buf[0] = b;
1
}
None => 0,
};
if offset == 1 && buf.len() == 1 {
// We've filled the buffer by using the previously peeked byte
Ok(1)
} else {
// We are still missing more bytes, so we read them from the
// underlying reader and place them directly in the correct place
// in the buffer.
Ok((self.inner.read(&mut buf[offset..]))? + offset)
}
}
}

Implement SType serialization (serialization::types) for missing types

see

impl SigmaSerializable for SType {
fn sigma_serialize<W: WriteSigmaVlqExt>(&self, _: W) -> Result<(), io::Error> {
// for reference see http://github.com/ScorexFoundation/sigmastate-interpreter/blob/25251c1313b0131835f92099f02cef8a5d932b5e/sigmastate/src/main/scala/sigmastate/serialization/TypeSerializer.scala#L25-L25
todo!()
}
fn sigma_parse<R: ReadSigmaVlqExt>(mut r: R) -> Result<Self, SerializationError> {
// for reference see http://github.com/ScorexFoundation/sigmastate-interpreter/blob/25251c1313b0131835f92099f02cef8a5d932b5e/sigmastate/src/main/scala/sigmastate/serialization/TypeSerializer.scala#L118-L118
let c = r.get_u8()?;
if c == 0 {
Err(SerializationError::InvalidTypePrefix)
} else {
todo!();
// Ok(SType::SAny)
}
}
}

Check that `EcPoint` serialization format is the same that used in sigmastate

I suppose taking some serialized random keys in sigmastate and check that Rust implementation produces the same result is enough.

Implementation in Rust:

impl SigmaSerializable for EcPoint {
fn sigma_serialize<W: vlq_encode::WriteSigmaVlqExt>(&self, w: &mut W) -> Result<(), io::Error> {
w.write_all(&self.0.serialize_compressed())?;
Ok(())
}
fn sigma_parse<R: vlq_encode::ReadSigmaVlqExt>(r: &mut R) -> Result<Self, SerializationError> {
let mut bytes = [0; EcPoint::PUBLIC_KEY_SIZE];
r.read_exact(&mut bytes[..])?;
let pk = PublicKey::parse_compressed(&bytes)
.map_err(|_| SerializationError::Misc("invalid secp256k1 compressed public key"))?;
Ok(EcPoint(pk))
}
}

In sigmastate:
https://github.com/ScorexFoundation/sigmastate-interpreter/blob/ec71a6f988f7412bc36199f46e7ad8db643478c7/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala#L7-L48

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.