Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mgpai22 committed Jan 23, 2024
0 parents commit 943cff7
Show file tree
Hide file tree
Showing 9 changed files with 570 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Tests

on:
push:
branches: ["main"]
pull_request:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- uses: aiken-lang/setup-aiken@v0.1.0
with:
version: v1

- run: aiken fmt --check
- run: aiken check -D
- run: aiken build
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Aiken compilation artifacts
artifacts/
# Aiken's project working directory
build/
# Aiken's default documentation export
docs/
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# winter-protocol

Write validators in the `validators` folder, and supporting functions in the `lib` folder using `.ak` as a file extension.

For example, as `validators/always_true.ak`

```gleam
validator {
fn spend(_datum: Data, _redeemer: Data, _context: Data) -> Bool {
True
}
}
```

## Building

```sh
aiken build
```

## Testing

You can write tests in any module using the `test` keyword. For example:

```gleam
test foo() {
1 + 1 == 2
}
```

To run all tests, simply do:

```sh
aiken check
```

To run only tests matching the string `foo`, do:

```sh
aiken check -m foo
```

## Documentation

If you're writing a library, you might want to generate an HTML documentation for it.

Use:

```sh
aiken docs
```

## Resources

Find more on the [Aiken's user manual](https://aiken-lang.org).
15 changes: 15 additions & 0 deletions aiken.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file was generated by Aiken
# You typically do not need to edit this file

[[requirements]]
name = "aiken-lang/stdlib"
version = "1.7.0"
source = "github"

[[packages]]
name = "aiken-lang/stdlib"
version = "1.7.0"
requirements = []
source = "github"

[etags]
14 changes: 14 additions & 0 deletions aiken.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name = "zengate/winter_protocol"
version = "0.0.0"
license = "Apache-2.0"
description = "Aiken contracts for project 'zengate/winter_protocol'"

[repository]
user = "zengate"
project = "winter_protocol"
platform = "github"

[[dependencies]]
name = "aiken-lang/stdlib"
version = "1.7.0"
source = "github"
62 changes: 62 additions & 0 deletions lib/winter_protocol/datums.ak
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use aiken/hash.{Blake2b_224, Blake2b_256, Hash}
use aiken/transaction.{
InlineDatum, Input, Output, OutputReference, Transaction, TransactionId,
}
use aiken/transaction/credential.{VerificationKey}

pub type VerificationKeyHash =
Hash<Blake2b_224, VerificationKey>

pub type ObjectDatum {
protocol_version: Int,
data_reference: ByteArray,
event_creation_info: Hash<Blake2b_256, Transaction>,
signers: List<VerificationKeyHash>,
}

pub fn valid_datum_recreation(
self_input: Input,
datum: ObjectDatum,
output: Output,
) -> Bool {
expect InlineDatum(output_datum) = output.datum
let casted_output_datum = to_object_datum(output_datum)
and {
datum.protocol_version == casted_output_datum.protocol_version,
datum.data_reference == casted_output_datum.data_reference,
valid_event_creation_info(self_input, datum, casted_output_datum),
datum.signers == casted_output_datum.signers,
}
}

fn valid_event_creation_info(
self_input: Input,
datum: ObjectDatum,
recreated_datum: ObjectDatum,
) -> Bool {
if datum.event_creation_info == "" {
recreated_datum.event_creation_info == self_input.output_reference.transaction_id.hash
} else {
recreated_datum.event_creation_info == datum.event_creation_info
}
}

fn to_object_datum(data: Data) -> ObjectDatum {
expect my_datum: ObjectDatum = data
my_datum
}

test must_cast_to_stake_pool_datum() {
let object_datum =
ObjectDatum {
protocol_version: 1,
data_reference: "ref",
event_creation_info: "",
signers: [
#"ad729530bbd009ad5e38034be47dc1f5b93b4ffeafa2963b4ef9846c",
#"b6d8be69da875267f9acf095456627153a88e08997c371d66f524b46",
],
}
let object_data: Data = object_datum
object_datum == to_object_datum(object_data)
}
39 changes: 39 additions & 0 deletions lib/winter_protocol/utils.ak
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use aiken/list
use aiken/transaction.{Output, Transaction}
use aiken/transaction/credential.{Address, PaymentCredential}
use aiken/transaction/value.{PolicyId}
use winter_protocol/datums.{VerificationKeyHash}

pub fn find_policy_id_outputs(
outputs: List<Output>,
policy_id: PolicyId,
) -> List<Output> {
list.filter(
outputs,
fn(output) { list.has(value.policies(output.value), policy_id) },
)
}

pub fn find_address_outputs(
outputs: List<Output>,
payment_credential: PaymentCredential,
) -> List<Output> {
list.filter(
outputs,
fn(output) { output.address.payment_credential == payment_credential },
)
}

pub fn must_be_signed_by_at_least_one(
transaction: Transaction,
vks: List<VerificationKeyHash>,
) -> Bool {
has_any(transaction.extra_signatories, vks)
}

pub fn has_any(
main_list: List<VerificationKeyHash>,
elements: List<VerificationKeyHash>,
) -> Bool {
list.any(elements, fn(element) { list.has(main_list, element) })
}
Loading

0 comments on commit 943cff7

Please sign in to comment.