Coder Social home page Coder Social logo

naumachia's Introduction

Naumachia


๐ŸŒŠ Mock your battles before you're out at sea ๐ŸŒŠ

Licence Crates.io Rust Build


Naumachia is a framework for writing Smart Contracts on the Cardano Blockchain using Rust!

Find us at the TxPipe Discord!

Work in Progress :)

Getting Started

Contributions

Pick up a good first issue

Excited to accept PRs and general feedback. There is a lot of work to be done to make this the best framework it can be, so I'll try to help onboard anyone interested in contributing.

Big fan of modern programming techniques. We are trying to prioritize

  1. End user experience (Devs and dApp users)
  2. Contributor experience + Maintainability
  3. Performance, once the other stuff is solid

Feel free to start issues/discussions if there are things you feel are missing or whatever. We love feedback!

FYI, CI requires these commands to pass. So, try to run them locally to save yourself some time.

cargo build --workspace
cargo test --workspace
cargo +nightly fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings

naumachia's People

Contributors

ch1n3du avatar kettlebell avatar microproofs avatar mitchturner avatar nielstron 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

Watchers

 avatar  avatar  avatar

naumachia's Issues

Make Address Generic and add variants

Right now it's just a String under the hood and there is no difference between wallet addresses, policies, and script addresses.

At the very least, we should reevaluate this.

Implement Minting for CML Client

Currently can't mint any native tokens on the real chain. This needs to be added to the issue implementation for CMLLedgerClient

Add fee calculation and inclusion in Txs.

Currently, there are no fees. We need to include for actual on-chain contracts. The fee calculation should be abstracted and possibly implemented on the TxoRecord, or whatever that becomes after more development.

`Address` implcity wants valid address

This is confusing, so maybe we just bite the bullet and force all addresses to be valid. It's just been nice to put Address::new("alice") into tests and not have to think about it being correct. But since some of our impls take a dep on Address and do in fact expect a certain shape, we kinda need to do something. Specifically, the test clients are affected. The live clients kinda force you into us real addresses, whereas in the test code, it'll just give you weird errors when it tries to convert into bytes and stuff.

We can do better.

Flesh out Transaction Context

The TxContext is very underdeveloped right now. Part of that is I don't know how it fits in. For example, it might only be relevant to our local, test ledger clients, so it might get moved there.

I like to keep as much as possible inside the Naumachia domain, but it's looking like a lot needs to be in our specific implementations.

Have `SmartContract` endpoint calls return the `tx_id`

When you hit an endpoint and it successfully submits a transaction, it will print the transaction id. We don't want this, we want it to return the tx_id and the caller can choose to print it if they'd like.

We can include a trace of the info as well if we want.

Push UTxO creation into LedgerClient impl where it belongs

This isn't a big surprise, but we need to introduce a better intermediary representation of the UTxO and then let the LedgerClient adapter deal with either iding them or letting the blockchain give you that info.

REgardless, it needs to be pushed out of the domain. There are a few TODOs scattered through the code that relates to this.

Add Aiken eval to Validator type to be used by all `.plutus` scripts

Currently the CMLValidator type (name not final) doesn't have an execute implementation because we need to give it some way to evaluate locally.

Aiken provides a way to evaluate (and even cost) locally. We 100% should use it at least for evaluating Plutus scripts locally.

`Datums` and `Redeemers` should be removed from the `SCLogic` trait`

Currently SCLogic includes the associated types:

    type Endpoints: Send + Sync;
    type Lookups: Send + Sync;
    type LookupResponses: Send + Sync;
    type Datums: Clone + Eq + Debug + Send + Sync;
    type Redeemers: Clone + PartialEq + Eq + Hash + Send + Sync;

This was meant to constrain the LedgerClient to be able to handle the correct Datums and Redeemers. This might not be necessary anymore, now that we have a domain concept of PlutusData and conversions between.

It might be better to put the conversion constraint at the implementation level if you want the conversion guarantees.

Allow additional support for multiple networks

There is limited support for using networks other than TESTNET currently. For example, the AlwaysSucceedsScript sample dApp's network is hard-coded, and it should be parameterized, or maybe the scripts shouldn't even worry about the network?

I think the easiest solution though is just adding a network(&self) -> u8 method to the LedgerClient trait. Then we don't need to worry about it and everyone has access to it that needs it.

Seems like a smell... A bit of a got type. But it's an easy solution for now.

Bug: Small input UTxO for `sample-dApps/mint_nft` breaks CML Change Balancing

"I'm using CML to build a TX for minting a one-shot token. Meaning I need to manually specify an input UTxO for the Policy to pass.

I've gotten it to work once, but I think I've encountered a subtle bug on my second run. The input it is specifying has the minimum Coin value, so it shouldn't be enough for an output after fees, but for some reason the let input_total = builder.get_total_input()?; in the method add_change_if_needed(), doesn't add any extra inputs to make up for the difference :(. i.e. add_change_if_needed() fails with the error
"Not enough ADA leftover to include non-ADA assets in a change address"

In playing around with the code, I removed the input UTxO from the transaction builder, just to see what inputs it gave me. And in that case it goes ahead and adds a big juicy UTxO to cover the fees + change (but of course the Policy fails on execution).
Is this a bug? Or could I be doing something different in the tx builder to help it add extra inputs?"

Introduce Asset Name into Native Tokens

Right now we just have PolicyId.

Maybe instead of Option<Address> this could be

enum PolicyId {
    ADA,
    Id(String),
    IdWithAssetName(String, String)
}

And then a From impl from Address or something.

Still sorting it out.

Dedupe the test Ledger Clients

These can be essentially the same code in a lot of places. It might just work to abstract the utxo storage part of it away behind a trait.

Make Datum/Redeemer method generics on `LedgerClient` instead of on the whole trait

This will make it more flexible.

Essentially, the signature is currently:

pub trait LedgerClient<Datum, Redeemer>: Send + Sync {
    ...
    async fn outputs_at_address(&self, address: &Address)
        -> LedgerClientResult<Vec<Output<Datum>>>;
    ...
    async fn issue(&self, tx: Transaction<Datum, Redeemer>) -> LedgerClientResult<()>;

and we can make it

pub trait LedgerClient: Send + Sync {
    ...
    async fn outputs_at_address<Datum>(&self, address: &Address)
        -> LedgerClientResult<Vec<Output<Datum>>>;
    ...
    async fn issue<Datum, Redeemer>(&self, tx: Transaction<Datum, Redeemer>) -> LedgerClientResult<()>;

Allow Datums and Redeemers for multiple validator scripts in a contract

Right now, my contracts are generic for just 1 type of datum and 1 type of redeemer. Granted, these can be enums, but, importantly, this still only allows 1 Validator per contract.

That's a bad constraint.

I want, at the very least, to provide a pattern to allow a contract writer to include multiple validator scripts in their contract. It might be as simple as doing nested datums and having one off-chain datum type that will hold the necessary on-chain datums, but we should make sure that this can be type checked before submission.

enum MyDatums {
    ValidatorA(ValidatorADatum),
    ValidatorB(ValidatorBDatum),
}

enum MyValidators {
    ValidatorA(ValidatorACode),
    ValidatorB(ValidatorBCode),
}

Something like this might work and just make the contract generic for MyDatums and your implementation will enable the matching to happen. But this is far from a pit-of-success solution for consumers. Might be a good stop-gap, since it's a less common pattern probably.

Complete Transaction Struct

This is the domain representation of a transaction, not the ledger representation. But everything that is included on a ledger transation needs to be represented here in some form--the information needs to be all here.

  • inputs
  • outputs
  • redeemers
  • validator scripts
  • minting policies
  • collateral
  • ...

Get eval tests working for Raw validator

They are broken right now because the Plutus scripts follow different patterns than Aiken, and I've been prioritizing Aiken. The best solution would be to rewrite the scripts in Aiken, but we can also do custom Constrs around some of the data types to make them work

Remove `Backend` in favor of `LedgerClient` directly

I don't think Backend is giving us much value at this point. Worth checking if we can just pass an LC in directly instead of dealing with the intermediate type.

The process method can just be added to the default methods on the LedgerClient trait.

Make Output ID generic

Right now we're using String for convenience, but it should depend on the TxORecord impl.

Add improved formatting

There are features in rust-fmt nightly that will automatically nest your imports. There might be other features as well that you can specify. This would tidy up a lot of files and would keep things tidy in the future.

Add `tracing` to Naumachia

This is long overdue. Let's add tracing to all the main intersections in Naumachia so consumers can use that for debugging, etc.

Parallelize CI tasks to improve speed

CI takes too long. I assume it's mostly the Aiken compilation that happens during the build process for each of the example projects.

I assume that if we split them up they could be handled by separate workers? That would parallelize the process.

Sort out output id generation in the testing Ledger Clients

Both the in memory and the local persisted ledger clients are just haphazardly creating tx_hashes. This won't break anything... so I haven't bothered changing that. But eventually we really need to do it in a sane way similar to how it's actually done, i.e. we need to have each tx only have one tx_hash and then manage all the indexes at once.

Test Backend Actions (Long lived)

Transfer

  • sending different amounts works
  • additional values in UTxOs don't get included
  • recipient's holdings don't interfere
  • can send to multiple recipients
  • can send multiple policies
  • not enough funds results in error
  • all transfers or none

Mint

  • Test can mint case
  • Test can not mint case with same script
  • ...

InitScript

  • ...

RedeemScriptOutput

  • ...

...More as added

Architectural diagram of Naumachia

Let's help people understand the structure and why things work the way they do. It might still change a lot, but at least we can document those changes and stuff if we have a baseline.

Use Minting Policies in Mint Action

Right now it just does what you tell it. We should use an actual minting policy with checks. Similar to the RedeemScriptOutput and ValidatorCode stuff.

Pin Aiken

Each release of Naumachia should have a pinned version of Aiken to get a deterministic script address mostly.

We might need a more robust solution to this long-term, but this is the first step.

Manage versioning with Changelog

We should use cargo-workspaces like they use in Aiken. Then we can keep track of changes in the Changelog and we don't need to bump the version with every commit.

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.