-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1511 from input-output-hk/damien/1495/add-example…
…-crate-for-cardano-transactions Add example crate for Cardano transactions
- Loading branch information
Showing
12 changed files
with
273 additions
and
23 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
target/ | ||
client-cardano-transaction | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[package] | ||
name = "client-cardano-transaction" | ||
description = "Mithril client cardano-transaction example" | ||
version = "0.1.0" | ||
authors = ["dev@iohk.io", "mithril-dev@iohk.io"] | ||
documentation = "https://mithril.network/doc" | ||
edition = "2021" | ||
homepage = "https://mithril.network" | ||
license = "Apache-2.0" | ||
repository = "https://github.com/input-output-hk/mithril/" | ||
|
||
[dependencies] | ||
anyhow = "1.0.79" | ||
clap = { version = "4.4.18", features = ["derive", "env"] } | ||
mithril-client = { path = "../../mithril-client", features = ["unstable"] } | ||
slog = "2.7.0" | ||
slog-async = "2.8.0" | ||
slog-term = "2.9.0" | ||
tokio = { version = "1.35.1", features = ["full"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Mithril client library example: Cardano transaction | ||
|
||
> [!WARNING] | ||
> This example makes use of unstable features of the Mithril client library. | ||
> Use them at your own risk, and expect possible modifications in future releases. | ||
> Please refer to the links provided at the end of this file for the most up-to-date developer documentation. | ||
## Description | ||
|
||
This example shows how to implement a Mithril client and use its features related to the `Cardano Transaction` type. | ||
|
||
In this example, the client interacts with an aggregator and performs the following operations: | ||
- Retrieve cryptographic proofs of membership of the Cardano transactions set for a list of transactions passed as arguments | ||
- Verify the validity of the proofs | ||
- Verify the validity of the validity of the certificate chain attached to the proofs | ||
- Verify that the certificate chain signs a message computed from the proof | ||
|
||
## Build and run the example | ||
|
||
```bash | ||
# Build from the crate directory | ||
cargo build | ||
|
||
# Run from the crate directory | ||
AGGREGATOR_ENDPOINT=YOUR_AGGREGATOR_ENDPOINT GENESIS_VERIFICATION_KEY=YOUR_GENESIS_VERIFICATION_KEY cargo run CARDANO_TX_HASH1,CARDANO_TX_HASH2,CARDANO_TX_HASH3 | ||
|
||
# Example with from 'testing-sanchonet' network | ||
AGGREGATOR_ENDPOINT=https://aggregator.testing-sanchonet.api.mithril.network/aggregator GENESIS_VERIFICATION_KEY=$(curl -s https://raw.githubusercontent.com/input-output-hk/mithril/main/mithril-infra/configuration/testing-sanchonet/genesis.vkey) cargo run db0dfab664045b117375a743a925385a7a3fa6a104f8bd95fa0f748088bcaff0,b457a094439cc5e371474f5758b4ecded3e1b035fe0717e39d78080e6fe169b2 | ||
``` | ||
|
||
## Links | ||
- **Developer documentation**: https://docs.rs/mithril-client/latest/mithril_client/ | ||
- **Crates.io**: https://crates.io/crates/mithril-client |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
//! This example shows how to implement a Mithril client and use its features. | ||
//! | ||
//! In this example, the client interacts with an aggregator whose URL must be specified in the command to get the data. | ||
|
||
use anyhow::anyhow; | ||
use clap::Parser; | ||
use slog::info; | ||
use std::sync::Arc; | ||
|
||
use mithril_client::common::TransactionHash; | ||
use mithril_client::{ClientBuilder, MessageBuilder, MithrilResult, VerifiedCardanoTransactions}; | ||
|
||
#[derive(Parser, Debug)] | ||
#[command(version)] | ||
pub struct Args { | ||
/// Genesis verification key. | ||
#[clap( | ||
long, | ||
env = "GENESIS_VERIFICATION_KEY", | ||
default_value = "5b3132372c37332c3132342c3136312c362c3133372c3133312c3231332c3230372c3131372c3139382c38352c3137362c3139392c3136322c3234312c36382c3132332c3131392c3134352c31332c3233322c3234332c34392c3232392c322c3234392c3230352c3230352c33392c3233352c34345d" | ||
)] | ||
genesis_verification_key: String, | ||
|
||
/// Aggregator endpoint URL. | ||
#[clap( | ||
long, | ||
env = "AGGREGATOR_ENDPOINT", | ||
default_value = "https://aggregator.testing-sanchonet.api.mithril.network/aggregator" | ||
)] | ||
aggregator_endpoint: String, | ||
|
||
/// Hashes of the transactions to certify. | ||
#[clap(value_delimiter = ',', required = true)] | ||
transactions_hashes: Vec<String>, | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() -> MithrilResult<()> { | ||
let args = Args::parse(); | ||
let transactions_hashes = &args | ||
.transactions_hashes | ||
.iter() | ||
.map(|s| s.as_str()) | ||
.collect::<Vec<&str>>(); | ||
let logger = build_logger(); | ||
let client = | ||
ClientBuilder::aggregator(&args.aggregator_endpoint, &args.genesis_verification_key) | ||
.with_logger(logger.clone()) | ||
.build()?; | ||
|
||
info!(logger, "Fetching a proof for the given transactions...",); | ||
let cardano_transaction_proof = client | ||
.cardano_transaction_proof() | ||
.get_proofs(transactions_hashes) | ||
.await | ||
.unwrap(); | ||
|
||
info!(logger, "Verifying the proof…",); | ||
let verified_transactions = cardano_transaction_proof.verify().unwrap(); | ||
|
||
info!( | ||
logger, | ||
"Fetching the associated certificate and verifying the certificate chain…", | ||
); | ||
let certificate = client | ||
.certificate() | ||
.verify_chain(&cardano_transaction_proof.certificate_hash) | ||
.await | ||
.unwrap(); | ||
|
||
info!( | ||
logger, | ||
"Verify that the proof is signed in the associated certificate", | ||
); | ||
let message = MessageBuilder::new() | ||
.compute_cardano_transactions_proofs_message(&certificate, &verified_transactions); | ||
if !certificate.match_message(&message) { | ||
return Err(anyhow!( | ||
"Proof and certificate doesn't match (certificate hash = '{}').", | ||
certificate.hash | ||
)); | ||
} | ||
|
||
log_certify_information( | ||
&verified_transactions, | ||
&cardano_transaction_proof.non_certified_transactions, | ||
); | ||
|
||
Ok(()) | ||
} | ||
|
||
pub fn log_certify_information( | ||
verified_transactions: &VerifiedCardanoTransactions, | ||
non_certified_transactions: &[TransactionHash], | ||
) { | ||
println!( | ||
r###"Cardano transactions with hashes "'{}'" have been successfully certified by Mithril."###, | ||
verified_transactions.certified_transactions().join(","), | ||
); | ||
|
||
if !non_certified_transactions.is_empty() { | ||
println!( | ||
r###"No proof could be computed for Cardano transactions with hashes "'{}'". | ||
Mithril may not have signed those transactions yet, please try again later."###, | ||
non_certified_transactions.join(","), | ||
); | ||
} | ||
} | ||
|
||
fn build_logger() -> slog::Logger { | ||
use slog::Drain; | ||
|
||
let decorator = slog_term::TermDecorator::new().build(); | ||
let drain = slog_term::FullFormat::new(decorator).build().fuse(); | ||
let drain = slog_async::Async::new(drain).build().fuse(); | ||
|
||
slog::Logger::root(Arc::new(drain), slog::o!()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.