Skip to content

Commit

Permalink
Merge pull request #7 from Rigidity/more-utilities-examples
Browse files Browse the repository at this point in the history
Add more stdlib and examples
  • Loading branch information
Rigidity authored Jun 24, 2024
2 parents ecc58e5 + 19abddb commit 68e495c
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 10 deletions.
3 changes: 3 additions & 0 deletions crates/rue-compiler/src/database/type_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ impl Database {
self.compare_type_visitor(*lhs, *rhs, ctx)
}
(_, Type::Optional(inner)) => self.compare_type_visitor(lhs, *inner, ctx),
(Type::Optional(inner), Type::Bytes) => {
Comparison::Castable & self.compare_type_visitor(*inner, rhs, ctx)
}

// TODO: Unions would make this more generalized and useful.
// I should add unions back.
Expand Down
2 changes: 1 addition & 1 deletion crates/rue-compiler/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ pub enum ErrorKind {
#[error("explicit return is not allowed in expressions")]
ExplicitReturnInExpr,

#[error("blocks must either have a an expression value, return statement, or raise an error")]
#[error("block missing return value")]
EmptyBlock,

#[error("cannot check equality on non-atom type `{0}`")]
Expand Down
2 changes: 2 additions & 0 deletions examples/multisig.rue
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// This puzzle has not been audited or tested, and is for example purposes only.

fun main(
public_keys: PublicKey[],
required: Int,
Expand Down
9 changes: 9 additions & 0 deletions examples/p2_conditions.rue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// This puzzle has not been audited or tested, and is for example purposes only.

fun main(public_key: PublicKey, conditions: Condition[]) -> Condition[] {
let agg_sig = Condition::AggSigMe {
public_key: public_key,
message: tree_hash(conditions),
};
[agg_sig, ...conditions]
}
25 changes: 25 additions & 0 deletions examples/p2_delegated_or_hidden.rue
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// This puzzle has not been audited or tested, and is for example purposes only.

fun main(
synthetic_pk: PublicKey,
original_pk: PublicKey?,
delegated_puzzle: fun(...Any) -> Condition[],
delegated_solution: Any
) -> Condition[] {
let conditions = delegated_puzzle(...delegated_solution);
let delegated_puzzle_hash = tree_hash(delegated_puzzle);

if original_pk != nil {
let exponent = sha256(original_pk as Bytes + delegated_puzzle_hash);
let offset_pk = pubkey_for_exp(exponent);
assert synthetic_pk == original_pk + offset_pk;
return conditions;
}

let agg_sig_me = Condition::AggSigMe {
public_key: synthetic_pk,
message: delegated_puzzle_hash,
};

[agg_sig_me, ...conditions]
}
77 changes: 68 additions & 9 deletions std/stdlib.rue
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,19 @@ export enum Condition {
},
}

export fun concat<T>(a: T[], b: T[]) -> T[] {
if a is (T, T[]) {
return [a.first, ...concat(a.rest, b)];
}
if b is (T, T[]) {
return [b.first, ...concat(a, b.rest)];
}
nil
}

inline const ATOM_PREFIX: Bytes = 1 as Bytes;
inline const PAIR_PREFIX: Bytes = 2 as Bytes;

export fun tree_hash(value: Any) -> Bytes32 {
if value is Bytes {
tree_hash_atom(value)
Expand All @@ -121,19 +134,65 @@ export fun tree_hash(value: Any) -> Bytes32 {
}

export inline fun tree_hash_atom(value: Bytes) -> Bytes32 {
sha256(1 as Bytes + value)
sha256(ATOM_PREFIX + value)
}

export inline fun tree_hash_pair(first: Bytes32, rest: Bytes32) -> Bytes32 {
sha256(2 as Bytes + first + rest)
sha256(PAIR_PREFIX + first + rest)
}

export fun concat<T>(a: T[], b: T[]) -> T[] {
if a is (T, T[]) {
return [a.first, ...concat(a.rest, b)];
}
if b is (T, T[]) {
return [b.first, ...concat(a, b.rest)];
inline const OP_Q: Bytes = 1 as Bytes;
inline const OP_A: Bytes = 2 as Bytes;
inline const OP_C: Bytes = 4 as Bytes;

inline const OP_Q_TREE_HASH: Bytes32 = tree_hash_atom(OP_Q);
inline const OP_A_TREE_HASH: Bytes32 = tree_hash_atom(OP_A);
inline const OP_C_TREE_HASH: Bytes32 = tree_hash_atom(OP_C);
inline const ONE_TREE_HASH: Bytes32 = tree_hash_atom(1 as Bytes);

const NIL_TREE_HASH: Bytes32 = tree_hash_atom(nil);
const APPLY_PREIMAGE_PREFIX: Bytes = PAIR_PREFIX + OP_A_TREE_HASH;
const CONS_PREIMAGE_PREFIX: Bytes = PAIR_PREFIX + OP_C_TREE_HASH;

inline fun quote_hash(value: Bytes32) -> Bytes32 {
tree_hash_pair(OP_Q_TREE_HASH, value)
}

inline fun two_item_list_hash(first: Bytes32, rest: Bytes32) -> Bytes32 {
tree_hash_pair(first, tree_hash_pair(rest, NIL_TREE_HASH))
}

inline fun apply_hash(mod_hash: Bytes32, environment_hash: Bytes32) -> Bytes32 {
sha256(APPLY_PREIMAGE_PREFIX + two_item_list_hash(quote_hash(mod_hash), environment_hash))
}

inline fun update_hash_with_parameter(
parameter_hash: Bytes32,
environment_hash: Bytes32
) -> Bytes32 {
sha256(CONS_PREIMAGE_PREFIX + two_item_list_hash(quote_hash(parameter_hash), environment_hash))
}

fun curried_params_hash(parameters: Bytes32[]) -> Bytes32 {
if parameters is Nil {
return ONE_TREE_HASH;
}
nil
update_hash_with_parameter(parameters.first, curried_params_hash(parameters.rest))
}

export inline fun curry_tree_hash(
mod_hash: Bytes32,
...parameters: Bytes32[]
) -> Bytes32 {
apply_hash(mod_hash, curried_params_hash(parameters))
}

export fun calculate_coin_id(
parent_coin_id: Bytes,
puzzle_hash: Bytes,
amount: Int,
) -> Bytes32 {
assert parent_coin_id is Bytes32;
assert puzzle_hash is Bytes32;
sha256(parent_coin_id + puzzle_hash + amount as Bytes)
}
1 change: 1 addition & 0 deletions test.clsp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2a
14 changes: 14 additions & 0 deletions tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,17 @@ compiler_errors = [
"unused inline function `some` at 6:12",
"unused let binding `inline_fun` at 2:9",
]

[p2_conditions]
bytes = 167
cost = 19407
input = "(0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ((51 0x291e4594b43d58e833cab95e4b165c5fac6b4d8391c81ebfd20efdd8d58b92d8 1000)))"
output = "((g1_multiply 0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0xc239bbcfc69fb5abacdd8dc174c6b33170c6d902dec3bc1c87662020cf044313) (g1_negate 0x291e4594b43d58e833cab95e4b165c5fac6b4d8391c81ebfd20efdd8d58b92d8 1000))"
hash = "abc43bf1142122da14e73971da004668ce7b8785ca2b6ac41427b8ef3193f957"

[p2_delegated_or_hidden]
bytes = 305
cost = 24974
input = "(0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 () (q . ((51 0x291e4594b43d58e833cab95e4b165c5fac6b4d8391c81ebfd20efdd8d58b92d8 1000))) 1)"
output = "((g1_multiply 0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0x3d7e1145b5969c12f4889f4f1f66bde0e4d3ba54b91784cf604294d162b44b69) (g1_negate 0x291e4594b43d58e833cab95e4b165c5fac6b4d8391c81ebfd20efdd8d58b92d8 1000))"
hash = "670f06e052dedc68788dd17acb7d100203a1533d11f9c679d0f23bd3d555f122"

0 comments on commit 68e495c

Please sign in to comment.