Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Valdryan Ivandito committed Oct 22, 2024
0 parents commit a9eb85a
Show file tree
Hide file tree
Showing 7 changed files with 295 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Continuous Integration

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

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: aiken-lang/setup-aiken@v1
with:
version: v1.1.4
- 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/
65 changes: 65 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# aiken-hello-world

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

```aiken
validator my_first_validator {
spend(_datum: Option<Data>, _redeemer: Data, _output_reference: Data, _context: Data) {
True
}
}
```

## Building

```sh
aiken build
```

## Configuring

**aiken.toml**
```toml
[config.default]
network_id = 41
```

Or, alternatively, write conditional environment modules under `env`.

## Testing

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

```aiken
use config
test foo() {
config.network_id + 1 == 42
}
```

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 = "v2.1.0"
source = "github"

[[packages]]
name = "aiken-lang/stdlib"
version = "v2.1.0"
requirements = []
source = "github"

[etags]
18 changes: 18 additions & 0 deletions aiken.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name = "aiken-lang/aiken-hello-world"
version = "0.0.0"
compiler = "v1.1.4"
plutus = "v3"
license = "Apache-2.0"
description = "Aiken contracts for project 'aiken-lang/aiken-hello-world'"

[repository]
user = "aiken-lang"
project = "aiken-hello-world"
platform = "github"

[[dependencies]]
name = "aiken-lang/stdlib"
version = "v2.1.0"
source = "github"

[config]
81 changes: 81 additions & 0 deletions plutus.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"preamble": {
"title": "aiken-lang/aiken-hello-world",
"description": "Aiken contracts for project 'aiken-lang/aiken-hello-world'",
"version": "0.0.0",
"plutusVersion": "v3",
"compiler": {
"name": "Aiken",
"version": "v1.1.4+79d0e45"
},
"license": "Apache-2.0"
},
"validators": [
{
"title": "hello_world.hello_world.spend",
"datum": {
"title": "datum",
"schema": {
"$ref": "#/definitions/hello_world~1Datum"
}
},
"redeemer": {
"title": "redeemer",
"schema": {
"$ref": "#/definitions/hello_world~1Redeemer"
}
},
"compiledCode": "59010301010032323232323225333002323232323253330073370e900118041baa0011323232533300a3370e900018059baa00513232533300f30110021533300c3370e900018069baa003132533300d3371e6eb8c044c03cdd50042450d48656c6c6f2c20576f726c642100100114a06644646600200200644a66602600229404c94ccc044cdc79bae301500200414a2266006006002602a0026eb0c040c044c044c044c044c044c044c044c044c038dd50049bae3010300e37546020601c6ea800c5858dd7180780098061baa00516300d300e002300c001300937540022c6014601600460120026012004600e00260086ea8004526136565734aae7555cf2ab9f5742ae89",
"hash": "fdd6640d1c9a4392dd7e829f0cc4e26766539c48b2cf594959e33559"
},
{
"title": "hello_world.hello_world.else",
"redeemer": {
"schema": {}
},
"compiledCode": "59010301010032323232323225333002323232323253330073370e900118041baa0011323232533300a3370e900018059baa00513232533300f30110021533300c3370e900018069baa003132533300d3371e6eb8c044c03cdd50042450d48656c6c6f2c20576f726c642100100114a06644646600200200644a66602600229404c94ccc044cdc79bae301500200414a2266006006002602a0026eb0c040c044c044c044c044c044c044c044c044c038dd50049bae3010300e37546020601c6ea800c5858dd7180780098061baa00516300d300e002300c001300937540022c6014601600460120026012004600e00260086ea8004526136565734aae7555cf2ab9f5742ae89",
"hash": "fdd6640d1c9a4392dd7e829f0cc4e26766539c48b2cf594959e33559"
}
],
"definitions": {
"ByteArray": {
"dataType": "bytes"
},
"VerificationKeyHash": {
"title": "VerificationKeyHash",
"dataType": "bytes"
},
"hello_world/Datum": {
"title": "Datum",
"anyOf": [
{
"title": "Datum",
"dataType": "constructor",
"index": 0,
"fields": [
{
"title": "owner",
"$ref": "#/definitions/VerificationKeyHash"
}
]
}
]
},
"hello_world/Redeemer": {
"title": "Redeemer",
"anyOf": [
{
"title": "Redeemer",
"dataType": "constructor",
"index": 0,
"fields": [
{
"title": "msg",
"$ref": "#/definitions/ByteArray"
}
]
}
]
}
}
}
92 changes: 92 additions & 0 deletions validators/hello_world.ak
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Library standar yang digunakan
use aiken/collection/list
use aiken/crypto.{VerificationKeyHash}
use aiken/primitive/string
use cardano/transaction.{OutputReference, Transaction}

// Mendefinisikan parameter datum berupa VerificationKeyHash dengan nama owner
// Datum menyimpan kunci verifikasi pemilik wallet
pub type Datum {
owner: VerificationKeyHash,
}

// Mendefinisikan parameter redeemer berupa ByteArray dengan nama msg
// Redeemer menyimpan pesan
pub type Redeemer {
msg: ByteArray,
}

// Validator hello_world merupakan fungsi utama
validator hello_world {
// Fungsi spend memvalidasi dua kondisi :
// redeemer harus "hello, world!" dan pemilik aset (di datum) harus menyetujui transaksi
spend(
datum: Option<Datum>,
redeemer: Redeemer,
_own_ref: OutputReference,
tx: Transaction,
) {
// Menampilkan isi dari redeemer di terminal ketika sesi testing
trace @"redeemer": string.from_bytearray(redeemer.msg)
// Konsep destructuring dan pattern matching dibutuhkan untuk memahami syntax ini
// Pada pattern matching terdapat Some dan None
// Jika parameter datum kosong maka hasilnya None
// Transaksi dibatalkan jika hasilnya None
expect Some(Datum { owner }) = datum
// Bernilai true jika pesan atau isi redeemer adalah "Hello, World!"
let must_say_hello = redeemer.msg == "Hello, World!"
// Bernilai true jika pemilik aset (di datum) menyetujui transaksi
let must_be_sign = list.has(tx.extra_signatories, owner)
// Operator ? digunakan untuk menampilkan dan menunjukan suatu parameter yang bernilai false
must_say_hello? && must_be_sign?
}

// Jika validasi gagal karena kondisi tidak terpenuhi maka transaksi dibatalkan
else(_) {
fail
}
}

// Skenario_1 : Pesan atau isi Redeemer tidak valid dan transaksi tidak disetujui user
test scenario_1() {
let datum =
Datum { owner: #"00000000000000000000000000000000000000000000000000000000" }
let redeemer = Redeemer { msg: "Aiken Rocks!" }
let placeholder_utxo = OutputReference { transaction_id: "", output_index: 0 }
hello_world.spend(
Some(datum),
redeemer,
placeholder_utxo,
transaction.placeholder,
)
}

// Skenario_2 : Pesan atau isi Redeemer valid dan transaksi tidak disetujui user
test scenario_2() {
let datum =
Datum { owner: #"00000000000000000000000000000000000000000000000000000000" }
let redeemer = Redeemer { msg: "Hello, World!" }
let placeholder_utxo = OutputReference { transaction_id: "", output_index: 0 }
hello_world.spend(
Some(datum),
redeemer,
placeholder_utxo,
transaction.placeholder,
)
}

// Skenario_3 : Pesan atau isi Redeemer valid dan transaksi disetujui user
test scenario_3() {
let datum =
Datum { owner: #"00000000000000000000000000000000000000000000000000000000" }
let redeemer = Redeemer { msg: "Hello, World!" }
let placeholder_utxo = OutputReference { transaction_id: "", output_index: 0 }
hello_world.spend(
Some(datum),
redeemer,
placeholder_utxo,
Transaction { ..transaction.placeholder, extra_signatories: [datum.owner] },
)
}


0 comments on commit a9eb85a

Please sign in to comment.