<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Satya on Medium]]></title>
        <description><![CDATA[Stories by Satya on Medium]]></description>
        <link>https://medium.com/@satran004?source=rss-3bb19096c001------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*wIXlPpOjskRT1s4j2zTsSQ.png</url>
            <title>Stories by Satya on Medium</title>
            <link>https://medium.com/@satran004?source=rss-3bb19096c001------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 03 Jun 2026 07:23:16 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@satran004/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Cardano Indexing Made Simple: Yaci Store Plugin System for Non-Java Developers]]></title>
            <link>https://satran004.medium.com/cardano-indexing-made-simple-yaci-store-plugin-system-for-non-java-developers-39d4c148ffb1?source=rss-3bb19096c001------2</link>
            <guid isPermaLink="false">https://medium.com/p/39d4c148ffb1</guid>
            <category><![CDATA[blockchain-indexer]]></category>
            <category><![CDATA[cardano-indexer]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[cardano]]></category>
            <category><![CDATA[yaci-store]]></category>
            <dc:creator><![CDATA[Satya]]></dc:creator>
            <pubDate>Wed, 20 Aug 2025 04:33:34 GMT</pubDate>
            <atom:updated>2025-08-20T04:35:51.314Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*r2isiLxteQ1JrCjp" /></figure><h3>Overview</h3><p><a href="https://store.yaci.xyz/">Yaci Store</a> is a modular, high-performance Cardano blockchain indexer and datastore that provides a flexible foundation for building blockchain applications.</p><p>At the core of Yaci Store are <strong>stores</strong>, which are essentially modules responsible for indexing specific types of data from the blockchain. Examples include transaction, UTXO, metadata, and staking stores, among many others. Some components require data from multiple stores, such as reward calculation (Ledger State calculation) and governance state calculation. We call these <strong>aggregates</strong>.</p><p>Yaci Store functions as both a standalone indexer and a library that can be integrated into any Spring Boot Java application to build custom indexers with only the required data. This approach is particularly useful for applications that need specific blockchain data or data from particular dApps without storing all blockchain information.</p><p>As a library, Yaci Store offers extensive customization options, allowing developers to build their own indexers and datastores tailored to their needs.</p><p>Yaci Store also ships with a default indexer that indexes all on-chain data and provides a comprehensive set of REST APIs to query the indexed information. Developers have the flexibility to disable stores they don’t need or turn off specific API endpoints when not required.</p><p>Starting with version 2.0.0-beta3, Yaci Store introduced a <strong>plugin system</strong> that allows developers to extend its functionality through custom plugins. These plugins can be written in <a href="http://mvel.documentnode.com/">MVEL</a> (a simple expression language), JavaScript, or Python.</p><p>With the plugin system, <strong>non-Java developers</strong> can now customize Yaci Store’s default behavior at a granular level. This was something previously only possible for Java developers using Yaci Store as a library in their applications. This capability is quite powerful and opens up many possibilities.</p><h3>Plugin Types</h3><p>Yaci Store currently supports two types of plugins:</p><h3>1. Storage Plugins</h3><p>These plugins extend Yaci Store’s storage capabilities by customizing the default behavior of storage implementations. There are three types of storage plugins:</p><ul><li><strong>Filter Plugin</strong>: Allows developers to filter what data to store</li><li><strong>Pre-Action Plugin</strong>: Enables data modification before storage</li><li><strong>Post-Action Plugin</strong>: Performs actions after data is stored (e.g., sending notifications or updating related data)</li></ul><p>Storage plugins are attached to predefined storage extension points. You can find the complete list of storage extension points in Yaci Store in the <a href="https://store.yaci.xyz/plugins/plugin_api-guide">plugin API guide</a>.</p><h3>2. Event Handler Plugins</h3><p>Event handler plugins let you listen to any Yaci Store event and perform actions based on those events. Previously, this capability was exclusive to Java developers, but now non-Java developers can also write event handler plugins in MVEL, JavaScript, or Python.</p><p>The full list of supported events is available in the <a href="https://store.yaci.xyz/plugins/plugin_api-guide">plugin API guide</a>.</p><h3>Getting Started with Yaci Store Plugin System</h3><h3>Distribution Options</h3><p>Yaci Store comes with two distribution types:</p><ol><li><strong>Docker Distribution Zip</strong></li><li><strong>Jar Distribution Zip</strong></li></ol><p>For the latest documentation on the 2.0.0 release, visit <a href="https://store.yaci.xyz">store.yaci.xyz</a>.</p><p>In this guide, we’ll focus on the Docker Distribution.</p><h3>Prerequisites</h3><ol><li>Download the latest Yaci Store Docker Distribution Zip from the <a href="https://github.com/bloxbean/yaci-store/releases/tag/v2.0.0-beta4">releases page</a> <br><strong>Note</strong>: <strong><em>Always check for the latest release version.</em></strong></li><li><strong>File to download</strong>: yaci-store-docker-2.0.0-beta4.zip</li><li>Unzip the downloaded file to your preferred directory. This creates a folder named yaci-store-docker-2.0.0-beta4.</li></ol><h3>File Structure</h3><p>The extracted directory contains:</p><ul><li><strong>config/</strong>: Configuration files for Yaci Store</li><li>application.properties: Main configuration file for customization</li><li>env: Environment variables file</li><li><strong>plugins/scripts</strong>: Directory for custom plugins (create subdirectories for organized plugin management)</li><li><strong>yaci-store.sh</strong>: Main script to start Yaci Store and the PostgreSQL database</li></ul><h3>Enabling Plugin Support</h3><p><strong>Step 1</strong>: Edit config/application-plugin.yml</p><p>Enable plugin support by setting enabled to true:</p><pre>store:<br>  plugins:<br>    enabled: true</pre><p><strong>Step 2</strong>: Enable JavaScript and Python Plugin Support (Optional)</p><p>If you plan to use JavaScript or Python plugins, edit config/env and uncomment:</p><pre>JDK_JAVA_OPTIONS=${JDK_JAVA_OPTIONS} -Dloader.path=plugins,plugins/lib,plugins/ext-jars</pre><h3>Example Use Cases</h3><h3>Example 1: Store Metadata with Specific Labels</h3><p>Our first use case demonstrates storing metadata with a specific label. Let’s say we want to store only metadata with the label “721”, which follows the Cardano <a href="https://cips.cardano.org/cip/CIP-25">CIP25</a> token metadata standard.</p><p>We’ll create a filter plugin that filters metadata based on the label using MVEL expressions.</p><p><strong>Plugin Configuration</strong>:</p><p>Create a filter plugin and attach it to the metadata.save storage extension point:</p><blockquote><strong><em>Note</em></strong><em>: Storage extension points are predefined hooks in storage implementations where you can attach custom behavior through storage plugins (filter, pre-action, post-action). For a complete list of storage extension points and domain models, visit the </em><a href="https://store.yaci.xyz/plugins/plugin_api-guide#storage-extension-points"><em>Yaci Store documentation</em></a><em>.</em></blockquote><p>Replace the content in config/application-plugins.yml with the following to filter metadata based on label. The provided expression will be evaluated for each metadata domain object before saving. In this example, we&#39;re using an MVEL expression, which is the easiest way to write a filter. For complex filter logic, you can create a separate script file with a filter method, as we&#39;ll see in the next example.</p><pre>store:<br>  plugins:<br>    enabled: true<br>    filters:<br>      metadata.save:<br>        - name: &quot;NFT Metadata Filter&quot;<br>          lang: mvel<br>          expression: label == &quot;721&quot;</pre><p><strong>Testing Configuration</strong>:</p><p>By default, application.properties is configured for public relays of the Preprod network, so we&#39;ll continue our example with that setup.</p><p>For testing purposes, you can set a custom start point instead of syncing from genesis. Edit config/application.properties:</p><pre># Add to config/application.properties<br>store.cardano.sync-start-slot=17558626<br>store.cardano.sync-start-blockhash=3b907cde82b21fb0511845072139aade67222a47c3dcbf90d1e6931b1ad1e30e</pre><p><strong>Starting Yaci Store</strong>:</p><p>Run the following command from the extracted directory:</p><pre>./yaci-store.sh start</pre><p><strong>Monitoring Logs</strong>:</p><p>Check the logs to verify your plugin is working:</p><pre>tail -f logs/yaci-store.log</pre><p><strong>Querying Indexed Metadata</strong>:</p><p>Once Yaci Store is running, query the indexed metadata:</p><pre>./psql.sh</pre><pre>-- Set the schema<br>SET search_path TO yaci_store;</pre><pre>-- Check that only NFT metadata (label 721) is stored<br>SELECT tx_hash, label FROM transaction_metadata;</pre><p>Now, before moving to the next example, let’s start with a fresh database:</p><ol><li><strong>Stop Yaci Store</strong> — This will stop both Yaci Store and the PostgreSQL database.</li></ol><pre>./yaci-store.sh stop</pre><p>2. <strong>Remove the data folder</strong></p><pre>rm -rf db-data</pre><h3>Example 2: Index UTXOs for a Specific Address</h3><p>This use case demonstrates creating plugins to index UTXOs for a specific address. We’ll store address-specific UTXOs in the address_utxo table and spent UTXOs in the tx_input table.</p><p>We’ll disable all other stores and enable only the UTXO store, then filter for UTXOs belonging to our target address.</p><p>Though it may appear simple, this use case has certain complexities. In this example, we’ll see how we can resolve those through plugins to demonstrate the flexibility the plugin framework provides.</p><p><strong>Target Address</strong>:</p><p>We are going to index the UTXOs for the following address.</p><p>addr_test1wzc86g4ym366hkaphryqqvaptwznqkmk2gdqz9930u534pcx58ahw</p><p><strong>General Configuration</strong>:</p><p>We’ll use the Preprod network. Since the default configuration already points to public Preprod relays, no network configuration changes are needed.</p><p><strong>Step 1</strong>: Update config/application.properties</p><p>Add the following configuration to disable all stores except the UTXO store.</p><pre>store.assets.enabled=false<br>store.blocks.enabled=false<br>store.epoch.enabled=false<br>store.metadata.enabled=false<br>store.mir.enabled=false<br>store.script.enabled=false<br>store.staking.enabled=false<br>store.transaction.enabled=false<br>store.utxo.enabled=true<br>store.governance.enabled=false</pre><p><strong>Step 2</strong>: Configure the target address and sync start point</p><pre>address.filter=addr_test1wzc86g4ym366hkaphryqqvaptwznqkmk2gdqz9930u534pcx58ahw</pre><p>Update/add the following sync start point. This point/block is just before the first transaction of this address on the Preprod network. To quickly check if our plugin works, let’s set the following point as our sync start point:</p><pre>store.cardano.sync-start-slot=66258805<br>store.cardano.sync-start-blockhash=2fd08baed1b092e4dda22306082f317e692d280f1e30d23bf8c88b566cd72cfe</pre><p><strong>Step 3</strong>: Discord Webhook URL (Optional)</p><p>If you want Discord notifications for balance changes, add the following configuration. This is an optional step for this example. You can also use any webhook for notifications through other systems. The Yaci Store Plugin framework provides an http variable that can be used to invoke webhook URLs from within plugins.</p><pre>discord.webhook.url=https://discord.com/api/webhooks/...</pre><h3>Required Plugins for This Use Case</h3><p>To store only UTXOs for our specific address, we need these plugins:</p><p><strong>1. Filter Plugin</strong>: Filters UTXOs by the configured address</p><p><strong>2. Event Handler Plugin for CommitEvent</strong>: During initial sync, Yaci Store processes blocks in batches of 100, with parallel processing within each batch for better performance. All storage plugins execute in parallel, but after processing each batch, Yaci Store publishes a CommitEvent that&#39;s processed sequentially.</p><p>Why do we need this? While filtering address_utxo records is straightforward (each record has an address field), filtering tx_input records is more challenging since they don&#39;t contain address information. The tx_input table represents spent outputs, enabling us to identify unspent UTXOs.</p><p>In the CommitEvent handler (called at the end of every batch after all UTXOs and inputs are saved), we’ll delete extra tx_input records by checking against the address_utxo table and removing inputs that don&#39;t have corresponding entries.</p><blockquote><strong>Note</strong>: Though not used in this example, the CommitEvent’s blockCaches field is a list of blocks processed in that batch (100 blocks during initial sync, 1 block at tip). This could be useful for finding block or transaction-related data if required for other use cases.</blockquote><p><strong>3. RollbackEvent Plugin to reset last tx input slot</strong>: This tracks the point up to which we’ve already deleted additional tx_inputs. This point helps limit our query condition when scanning the tx_inputs table. During rollback, we need to reset this point to the rollback point.</p><p><strong>4. Event Handler Plugin for Notifications</strong> (Optional): Send Discord notifications whenever there’s a balance change.</p><h3>Plugin Configuration</h3><p>Replace these three plugins in config/application-plugins.yml:</p><pre>store:<br>  plugins:<br>    enabled: true<br>    exit-on-error: true<br><br>    filters:<br>      utxo.unspent.save:<br>        - name: Filter by address<br>          lang: mvel<br>          script: <br>            file: /app/plugins/scripts/utxo.mvel<br>            function: filterByAddress<br><br>    event-handlers:<br>      CommitEvent:<br>        - name: &quot;Delete additional tx inputs&quot;<br>          lang: mvel<br>          script: <br>            file: /app/plugins/scripts/utxo.mvel<br>            function: handleCommitEvent          <br>        - name: &quot;Send Balance Change Notification&quot;<br>          lang: mvel<br>          script: <br>            file: /app/plugins/scripts/utxo.mvel<br>            function: sendDiscordNotificationOnBalanceChange<br>            <br>      RollbackEvent:<br>        - name: &quot;Reset last_tx_input_slot&quot;<br>          lang: mvel<br>          script: <br>            file: /app/plugins/scripts/utxo.mvel<br>            function: handleRollbackEvent</pre><p>In the plugins/scripts/ directory, create a utxo.mvel file with the following content:</p><pre>/**<br> * Yaci Store UTXO Plugin Script<br> * This script provides functionality for filtering UTXOs by address before storing in address_utxo table.<br> * It also remove extra tx_inputs records through handling commit events<br> */<br><br>/**<br> * Filters a list of UTXO items by a specific address<br> * @param items - List of UTXO items to filter<br> * @return List of filtered UTXOs that match the address filter<br> */<br>def filterByAddress(items) {<br>    // Initialize empty list to store filtered results<br>    filteredUtxos = [];<br>    <br>    // Get the address filter from environment configuration<br>    address = env.getProperty(&quot;address.filter&quot;);<br>    <br>    // Iterate through all UTXO items and filter by owner address<br>    for (item: items) {<br>        if (item.ownerAddr == address) {<br>            filteredUtxos.add(item);<br>        }<br>    }<br>    <br>    // If any UTXOs were found, update global state and log the count<br>    if (filteredUtxos.size() &gt; 0) {<br>        global_state.put(&quot;utxo.found&quot;, true);<br>    }<br>    <br>    return filteredUtxos;<br>}<br><br>/**<br> * Handles commit events by cleaning up additional transaction inputs<br> * <br> * Since tx_input records don&#39;t have address filtering and Yaci Store processes <br> * blocks in parallel batches (100 blocks during initial sync, 1 block at tip), tx_input <br> * records may be inserted before their corresponding UTXO entries in address_utxo table. <br> * The CommitEvent is published at the end of each batch and handlers are processed <br> * sequentially, making it the perfect place to delete orphaned tx_input records.<br> * <br> * @param event - The commit event containing metadata like slot number<br> */<br>def handleCommitEvent(event) {<br>    // Get the last processed slot from state, default to 0 if not set<br>    // In this case, we are using plugin state to store last_tx_input_slot<br>    last_tx_inputs_slot = global_state.get(&quot;last_tx_inputs_slot&quot;);<br>    if (last_tx_inputs_slot == null) {<br>        last_tx_inputs_slot = 0;<br>    }<br><br>    System.out.println(&quot;Deleting additional tx inputs after slot: &quot; + last_tx_inputs_slot);<br><br>    // SQL query to delete orphaned tx_input records<br>    // Only deletes records that are not referenced by address_utxo table<br>    sql = &quot;DELETE FROM tx_input ti &quot; +<br>            &quot;WHERE ti.spent_at_slot &gt; :given_slot &quot; +<br>            &quot;AND NOT EXISTS ( &quot; +<br>            &quot;  SELECT 1 FROM address_utxo au &quot; +<br>            &quot;  WHERE au.tx_hash = ti.tx_hash &quot; +<br>            &quot;    AND au.output_index = ti.output_index &quot; +<br>            &quot;)&quot;;<br><br>    // Set parameters for the SQL query<br>    params = [ &quot;given_slot&quot; : last_tx_inputs_slot ];<br>    <br>    // Execute the delete operation and get count of deleted records<br>    count = named_jdbc.update(sql, params);<br><br>    // Log the number of deleted records if any were found<br>    if (count &gt; 0) {<br>        System.out.println(&quot;Deleted &quot; + count + &quot; additional tx inputs.&quot;);<br>    }<br><br>    // Update the last processed slot to current event slot<br>    global_state.put(&quot;last_tx_inputs_slot&quot;, event.metadata.slot);<br>}<br><br>def handleRollbackEvent(event) {<br>    //Reset last_tx_input_slot<br>    System.out.println(&quot;Utxo by address plugin handleRollbackEvent: &quot; + event.rollbackTo.slot);<br>    global_state.put(&quot;last_tx_inputs_slot&quot;, event.rollbackTo.slot);<br>}<br><br>def sendDiscordNotificationOnBalanceChange(event) {<br>    utxoFound = global_state.get(&quot;utxo.found&quot;);<br>    <br>    if (utxoFound != null &amp;&amp; utxoFound) {<br>        global_state.remove(&quot;utxo.found&quot;);<br><br>        // Skip sending notification if not at tip yet<br>        if (!event.metadata.syncMode) {<br>            return;<br>        }<br><br>        address = env.getProperty(&quot;address.filter&quot;);    <br><br>        sql = &quot;SELECT SUM(au.lovelace_amount) AS balance &quot; +<br>            &quot;FROM address_utxo au &quot; +<br>            &quot;WHERE au.owner_addr = :address &quot; +<br>            &quot;AND NOT EXISTS (SELECT 1 FROM tx_input ti WHERE ti.tx_hash = au.tx_hash AND ti.output_index = au.output_index)&quot;;<br><br>        params = [ &quot;address&quot; : address ];<br>        <br>        result = named_jdbc.queryForMap(sql, params);<br>        balance = result[&quot;balance&quot;];<br><br>        discordUrl = env.getProperty(&quot;discord.webhook.url&quot;);<br><br>        jsonData = [&quot;content&quot;: &quot;💰 Unspent UTXO Balance: &quot; + balance + &quot; Lovelace at Block: &quot; + event.metadata.block +&quot;\n Address: &quot; + address];<br>        response = http.postJson(discordUrl, jsonData, [&quot;Content-Type&quot;: &quot;application/json&quot;]);<br>        System.out.println(&quot;Discord response: &quot; + response);<br>    }<br>}</pre><h3>Running the Example</h3><ol><li>If you have an existing database, remove the db-data folder</li><li>Start Yaci Store:</li></ol><pre>./yaci-store.sh start</pre><p>3. Check the log file in the logs folder to see if the sync is working properly.</p><p>4. After some time, verify the results:</p><pre>./psql.sh</pre><pre>SET search_path TO yaci_store;<br>SELECT owner_addr FROM address_utxo;</pre><p>You should only see UTXOs with our configured address as the owner_addr.</p><h3>Alternative Languages</h3><p>While this example uses MVEL, you can also write plugins in JavaScript or Python. JavaScript and Python plugins are currently in preview status, enabled through GraalVM polyglot support. The current Docker distribution bundles standard JDK 24, but future releases will include GraalVM JDK as an option for better JavaScript and Python plugin performance.</p><p>You can find JavaScript and Python versions of this plugin in the <a href="https://github.com/bloxbean/yaci-store-plugins/tree/main/utxos-by-address">yaci-store-plugins repository</a>. The function names remain the same across MVEL, JavaScript, and Python implementations.</p><blockquote><strong>Note</strong>: Unlike MVEL, in JavaScript and Python plugins, you cannot access fields directly through field names. You must use getter methods instead.</blockquote><blockquote><strong>Wrong</strong>: event.metadata.slot<br><strong>Correct</strong>: event.getMetadata().getSlot()</blockquote><h3>Debugging Tips</h3><p><strong>Console Output</strong>:</p><ul><li>MVEL: Use System.out.println()</li><li>JavaScript: Use console.log()</li><li>Python: Use print()</li></ul><p><strong>Exception Handling</strong>: Check the log file at logs/yaci-store.log. Exception stack traces can be lengthy, so scroll to the beginning to find the root cause.</p><p>For non-Java developers, the current logging approach might feel overwhelming. We plan to introduce a separate plugin log file in future versions to improve the debugging experience.</p><h3>Conclusion</h3><p>The Yaci Store plugin system democratizes Cardano blockchain indexing customization, making it accessible to developers regardless of their programming language background. Whether you’re filtering specific metadata, tracking address-specific UTXOs, or building complex event-driven workflows, the plugin system provides the flexibility you need without requiring Java expertise.</p><p>This is just the beginning — the plugin system opens up countless possibilities for customizing your blockchain data indexing workflow. Happy building!</p><h3>Resources</h3><p><strong>Yaci Store GitHub:</strong> <a href="https://github.com/bloxbean/yaci-store">https://github.com/bloxbean/yaci-store</a><br><strong>Yaci Store Doc: </strong><a href="https://store.yaci.xyz/">https://store.yaci.xyz/</a><br><strong>Yaci Store Plugin repository:</strong> <a href="https://github.com/bloxbean/yaci-store-plugins">https://github.com/bloxbean/yaci-store-plugins</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=39d4c148ffb1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing new QuickTx API in Cardano Client Lib 0.5.0-beta1]]></title>
            <link>https://satran004.medium.com/introducing-new-quicktx-api-in-cardano-client-lib-0-5-0-beta1-5beb491282ce?source=rss-3bb19096c001------2</link>
            <guid isPermaLink="false">https://medium.com/p/5beb491282ce</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[smart-contracts]]></category>
            <category><![CDATA[cardano]]></category>
            <category><![CDATA[cardano-client-lib]]></category>
            <dc:creator><![CDATA[Satya]]></dc:creator>
            <pubDate>Fri, 18 Aug 2023 15:47:55 GMT</pubDate>
            <atom:updated>2023-08-18T15:47:55.236Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*89CBRYZgrz1rMabOf0GUVQ.jpeg" /></figure><p>With the release of <a href="https://github.com/bloxbean/cardano-client-lib">Cardano Client Lib</a> <strong>0.5.0-beta1</strong>, we now have a new transaction builder API known as <strong>QuickTx</strong>. This post aims to provide an overview of this new API and demonstrate its utility.</p><p>Historically, Cardano Client Lib began with a <strong>high-level API</strong> for building payment or token mint transactions. While this provided simplicity, it lacked flexibility and support for more advanced transactions, such as those involving smart contracts.</p><p>To bridge this gap, the <strong>Composable Functions API</strong> was later introduced, offering flexibility and supporting various transaction types. This API provided out-of-the-box composable functions and allowed developers to write their custom functions for the TxBuilder API. However, it compromised on simplicity.</p><p>Enter <strong>QuickTx</strong>. This new transaction builder API strikes a balance between simplicity and flexibility. It’s built upon the Composable Functions API and offers a more streamlined experience, supporting an extensive range of transactions. Those familiar with the <a href="https://lucid.spacebudz.io/">Lucid JS</a> library will notice many similarities.</p><h3><strong>High-Level Concepts — QuickTx</strong></h3><p>Before diving into examples, let’s first explore some foundational concepts of QuickTx.</p><p>QuickTx API revolves around two main classes —<strong> </strong><strong>Tx</strong> and <strong>ScriptTx</strong> – to declare different parts of a transaction or transaction fragments. These fragments are later composed by a new builder class, <strong>QuickTxBuilder</strong>, to construct the final transaction.</p><ol><li><strong>Tx</strong></li></ol><p>This class is for transactions from regular (non-script) addresses. You can declaratively define a transaction from an address using this class. Each instance must have a unique sender. Transaction types for the Tx class include:</p><ul><li><em>Transfers (address-to-address, non-script to script for fund locking)</em></li><li><em>Token operations (minting, burning)</em></li><li><em>Stake address operations (registration, de-registration, delegation)</em></li><li><em>Pool operations (registration, update, retirement)</em></li><li><em>Reward withdrawal</em></li></ul><p><strong>2. ScriptTx</strong></p><p>This class can be used for transactions where a script witness is needed, like for transactions from a script address. With one <strong>ScriptTx</strong> instance, multiple script calls (spending, minting, etc.) can be declared together.</p><p><strong>3. QuickTxBuilder</strong></p><p>This class allows composition of multiple Tx and ScriptTx instances to create the final transaction. Beyond building the transaction, QuickTxBuilder also supports transaction signing and submission. Through Txcontxt, callbacks like “postBalanceTx” and “preBalanceTx” allow insertion of custom TxBuilder functions for application-specific customization.</p><p>Enough theory, let’s delve into some examples.</p><h3><strong>Setup and Pre-requisites</strong></h3><p><strong>Accounts<br></strong> <br>For transactions, we need accounts. Here, we’ll set up a few testnet accounts for our examples:</p><pre>Account sender1 = new Account(Networks.testnet(), mnemonic);<br>String sender1Addr = sender1.baseAddress();<br><br>Account sender2 = new Account(Networks.testnet(), mnemonic);<br>String sender2Addr = sender2.baseAddress();<br><br>String receiver1 = new Account(Networks.testnet(), mnemonic).baseAddress();</pre><p>You can use any of the public testnets, such as Preprod or Preview. Please send some test Ada from the corresponding testnet faucet.<br><strong><br>Backend Service</strong></p><p>Create a BackendService instance for any of the supported backends (Blockfrost, Koios, Ogmios/Kupo, etc.). Alternatively, you can create your own backend implementation by implementing supplier interfaces such as UtxoSupplier, ProtocolParamsSupplier, and TransactionProcessor. However, to keep this blog post simple, let’s use one of the out-of-the-box providers</p><pre>var backendService = new BFBackendService(Constants.BLOCKFROST_PREPROD_URL, bfProjectId);<br><br>or<br><br>var backendService = new KoiosBackendService(KOIOS_PREPROD_URL);<br><br>or <br><br>var backendService = new KupmiosBackendService(ogmiosUrl, kupoUrl)</pre><h3><strong>Transactions with QuickTx</strong></h3><p>Having set up the account and backend service correctly, we are now prepared to submit our first transaction.</p><ol><li><strong>A Simple Transfer from Sender to Receiver</strong></li></ol><p>Send test Ada from sender1 to receiver1 and attach a CIP20 message as metadata.</p><ul><li>Declare a transaction to pay Ada to receiver1.</li></ul><pre>Tx tx = new Tx()<br>       .payToAddress(receiver1, Amount.ada(5))<br>       .attachMetadata(MessageMetadata.create().add(&quot;This is a test message&quot;))<br>       .from(sender1Addr);</pre><blockquote><strong>Note</strong>: The from field must be set for Tx</blockquote><ul><li>Build and submit the transaction to Cardano network</li></ul><pre>QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService);<br>Result&lt;String&gt; result = quickTxBuilder.compose(tx)<br>       .withSigner(SignerProviders.signerFrom(sender1))<br>       .complete();</pre><p>The QuickTxBuilder class constructs the final transaction using tx, signs it, and submits it to a Cardano node through backend service. If the transaction is valid, result.getValue() returns the transaction hash. To wait for the transaction to be included in a block, utilize the completeAndWait function:</p><pre>Result&lt;String&gt; result = quickTxBuilder.compose(tx)<br>       .withSigner(SignerProviders.signerFrom(sender1))<br>       .completeAndWait(System.out::println);</pre><p>2. <strong>Send Transfer to Two Separate Addresses :- Composing Two Payments</strong></p><p>Transfer test Ada from sender1 to receiver1 and from sender2 to receiver2 in one transaction.</p><ul><li>Declarations:</li></ul><pre>Tx tx1 = new Tx()<br>       .payToAddress(receiver1, Amount.ada(5))<br>       .from(sender1Addr);<br><br>Tx tx2 = new Tx()<br>       .payToAddress(receiver2, Amount.ada(4.5))<br>       .from(sender2Addr);</pre><ul><li>Compose and submit:</li></ul><pre>Result&lt;String&gt; result = quickTxBuilder.compose(tx1, tx2)<br>       .feePayer(sender1Addr)<br>       .withSigner(SignerProviders.signerFrom(sender1))<br>       .withSigner(SignerProviders.signerFrom(sender2))<br>       .completeAndWait(System.out::println);</pre><blockquote><strong>Note</strong>: The feePayer() method sets sender1Addr as the fee payer, a requisite step when merging multiple Tx transactions.</blockquote><p><strong>3. Token Minting</strong></p><ul><li>Setup — Create a policy. Define asset name and quantity</li></ul><pre>Policy policy = PolicyUtil.createMultiSigScriptAtLeastPolicy(&quot;test_policy&quot;, 1, 1);<br>String assetName = &quot;MyAsset&quot;;<br>BigInteger qty = BigInteger.valueOf(200);</pre><ul><li>Declare minting transaction</li></ul><p><em>In the code snippet below:</em></p><p><strong><em>a.</em></strong><em> Create a new Tx.<br></em><strong><em>b.</em></strong><em> Declare </em><em>mintAsset with required information such as </em><em>policyScript, </em><em>asset, and the receiver address which will receive the newly minted token.<br></em><strong><em>c.</em></strong><em> Define a ‘from’ address.</em></p><pre>Tx tx = new Tx()<br>       .mintAssets(policy.getPolicyScript(), new Asset(assetName, qty), sender1Addr)<br>       .attachMetadata(MessageMetadata.create().add(&quot;Minting tx&quot;))<br>       .from(sender1Addr);</pre><ul><li>Build, Sign and Submit transaction</li></ul><blockquote>To build and submit a transaction, the steps are exactly the same. Use QuickTxBuilder to compose the Tx, and sign the transaction with both the sender1 account and the policy script.</blockquote><pre>Result&lt;String&gt; result = quickTxBuilder.compose(tx)<br>       .withSigner(SignerProviders.signerFrom(sender1))<br>       .withSigner(SignerProviders.signerFrom(policy))<br>       .completeAndWait(System.out::println);</pre><p>4. <strong>Minting Tokens and Distributing to Two Addresses</strong></p><ul><li>Declare transaction</li></ul><pre>BigInteger qty = BigInteger.valueOf(200);<br>Tx tx = new Tx()<br>          .mintAssets(policy.getPolicyScript(), new Asset(assetName, qty))<br>          .payToAddress(receiver1, Amount.asset(policy.getPolicyId(), assetName, 100))<br>          .payToAddress(receiver2, Amount.asset(policy.getPolicyId(), assetName, 100))<br>          .from(sender1Addr);</pre><blockquote>Mint 200 tokens and transfer 100 tokens each to receiver1 and receiver2.</blockquote><p>5. <strong>Mint and Pay using Two Separate Senders</strong></p><ul><li>Declare transactions</li></ul><pre>Tx tx1 = new Tx()<br>       .payToAddress(receiver1, Amount.ada(1.5))<br>       .mintAssets(policy.getPolicyScript(), new Asset(assetName, qty), receiver2)<br>       .from(sender1Addr);<br><br>Tx tx2 = new Tx()<br>       .payToAddress(receiver2, Amount.ada(3))<br>       .from(sender2Addr);</pre><blockquote>The first transaction (tx1) deducts 1.5 ADA from the sender1 address to pay receiver1, and it mints 200 new tokens which are also sent to receiver2.</blockquote><blockquote>The second transaction (tx2) pays receiver2 3 ADA.</blockquote><ul><li>Compose to build transaction and submit</li></ul><pre>Result&lt;String&gt; result = quickTxBuilder.compose(tx1, tx2)<br>       .feePayer(sender1.baseAddress())<br>       .withSigner(SignerProviders.signerFrom(sender1))<br>       .withSigner(SignerProviders.signerFrom(sender2))<br>       .withSigner(SignerProviders.signerFrom(policy))<br>       .completeAndWait(System.out::println);</pre><blockquote>Both Tx instances are combined to construct the final transaction. Note that we are signing the transaction with three signers: Sender1, Sender2, and the policy script.</blockquote><p>6. <strong>Stake Address Registration</strong></p><p>For tasks like stake key registration, de-registration, and delegation, QuickTx significantly simplifies the process.</p><ul><li>Registering the stake address:</li></ul><pre>Tx tx = new Tx()<br>       .registerStakeAddress(sender1Addr)<br>       .from(sender1Addr);<br><br>Result&lt;String&gt; result = quickTxBuilder.compose(tx)<br>       .withSigner(SignerProviders.signerFrom(sender1))<br>       .completeAndWait(msg -&gt; System.out.println(msg));</pre><p>7. <strong>Stake Key De-Registration</strong></p><p>The transaction below will deregister the stake key and send the deposit back to sender1Addr. To de-register stake key, sign with account’s stake key and for fee payment, sign with account.</p><pre> Tx tx = new Tx()<br>           .deregisterStakeAddress(sender1Addr)<br>           .from(sender1Addr);<br><br> Result&lt;String&gt; result = quickTxBuilder.compose(tx)<br>           .withSigner(SignerProviders.signerFrom(sender1))<br>           .withSigner(SignerProviders.stakeKeySignerFrom(sender1))<br>           .completeAndWait(msg -&gt; System.out.println(msg));</pre><blockquote>For delegation and reward withdrawal, you can use delegateTo and withdraw methods, respectively.</blockquote><h3>Script / Smart Contract Transactions</h3><p>In this section, we will explore some basic examples of smart contract transactions using QuickTx. This is just an introduction, and I’ll provide a more detailed step-by-step guide later in a separate blog post.</p><h3>Pr-requisites</h3><p>For smart contract transactions, you need both a PlutusScript and a script address. You can obtain a contract address from a PlutusScript object using the AddressProvider.</p><pre>PlutusV2Script plutusScript = PlutusV2Script.builder()<br>                                .type(&quot;PlutusScriptV2&quot;)<br>                                .cborHex(&quot;49480100002221200101&quot;)<br>                                .build();</pre><p>The script above represents the well-known <strong>alwaysTrue</strong> script that always returns true. To retrieve the script address:</p><pre>String scriptAddress = AddressProvider.getEntAddress(plutusScript, Networks.testnet()).toBech32();</pre><blockquote><strong>Note:</strong> For mainnet addresses, use Networks.mainnet().</blockquote><h3>1. Lock Fund</h3><p>To secure funds at a script address with inline datum, use the payToContract() method from the Tx class:</p><pre>BigIntPlutusData datumData = BigIntPlutusData.of(40);<br><br>Tx tx = new Tx()<br>            .payToContract(scriptAddress, Amount.ada(10), datumData)<br>            .from(sender2Addr);<br><br>Result&lt;String&gt; txResult = quickTxBuilder.compose(tx)<br>                .withSigner(SignerProviders.signerFrom(sender2))<br>                .completeAndWait(System.out::println);</pre><p>In the code above, we are attempting to lock 10 Ada and datum 40 at the script address. The secured Ada can now only be accessed via a smart contract or script transaction.</p><h3>2. Unlock funds at a contract address</h3><p>Initially, find the UTXO(s) where the value is locked. Use the ScriptUtxoFinders class to achieve this:</p><pre>UtxoSupplier utxoSupplier = new DefaultUtxoSupplier(backendService.getUtxoService());<br>Optional&lt;Utxo&gt; optionalUtxo = ScriptUtxoFinders.findFirstByInlineDatum(utxoSupplier, scriptAddress, datumData);</pre><p>Now create a ScriptTx instance:</p><pre>PlutusData redeemer = PlutusData.unit(); //any data for this contract<br>ScriptTx scriptTx = new ScriptTx()<br>                          .collectFrom(optionalUtxo.get(), redeemer)<br>                          .payToAddress(receiver1, Amount.ada(10))<br>                          .attachSpendingValidator(plutusScript);</pre><p>In the above snippet, the collectFrom() method declares the input utxo(s) for this script transaction. The second parameter of the collectFrom method accepts redeemer data.</p><p>Next, we transfer the unlocked funds to receiver1. Finally, a spending validator can be attached using the attachSpendingValidator method.</p><blockquote>To partially transfer locked funds to a receiver, you can use the withChangeAddress(address, datum) method. This refunds the remaining amount either to the script address or to any other specified address.</blockquote><p>You can now build and submit the transaction using the familiar QuickTxBuilder:</p><pre>Result&lt;String&gt; result = quickTxBuilder.compose(scriptTx)<br>    .feePayer(sender1Addr)<br>    .withSigner(SignerProviders.signerFrom(sender1))<br>    .completeAndWait(System.out::println);</pre><p>Remember, QuickTxBuilder automatically evaluates script transactions to calculate script cost by invoking the evaluateTx method from backend service.</p><p>However, for in-app script cost evaluations without backend service dependency, you can use <strong>AikenTransactionEvaluator.</strong></p><pre>ProtocolParamsSupplier protocolParamsSupplier = new DefaultProtocolParamsSupplier(backendService.getEpochService());<br>Result&lt;String&gt; result = quickTxBuilder.compose(scriptTx)<br>                .feePayer(sender1Addr)<br>                .withSigner(SignerProviders.signerFrom(sender1))<br>                .withTxEvaluator(new AikenTransactionEvaluator(utxoSupplier, protocolParamsSupplier))<br>                .completeAndWait(System.out::println);</pre><blockquote>Note: It’s possible to incorporate multiple script calls or attach multiple spending validators in one ScriptTx instance.</blockquote><h3>2. Mint tokens with Script</h3><p>To mint tokens using PlutusScript, initiate a ScriptTx instance and invoke mintAsset(). The following example demonstrates minting three separate tokens:</p><pre>ScriptTx scriptTx = new ScriptTx()<br>    .mintAsset(plutusScript1, asset1, BigIntPlutusData.of(1), receiver1)<br>    .mintAsset(plutusScript2, asset2, BigIntPlutusData.of(2), sender1Addr)<br>    .mintAsset(plutusScript3, asset3, BigIntPlutusData.of(3), receiver1)<br>    .withChangeAddress(sender1Addr);<br><br>Result&lt;String&gt; result1 = quickTxBuilder.compose(scriptTx)<br>    .feePayer(sender1Addr)<br>    .withSigner(SignerProviders.signerFrom(sender1))<br>    .completeAndWait(System.out::println);</pre><p>With ScriptTx, you can also handle reference inputs and execute various transaction types.</p><h3>Conclusion</h3><p>Thank you for taking the time to go through this guide with me. Stay tuned for more in-depth tutorials on working with Cardano Client Lib. If you have any questions or feedback, please don’t hesitate to reach out.</p><p>Happy coding!</p><h3>Resources</h3><ol><li>Cardano Client Lib GitHub — <a href="https://github.com/bloxbean/cardano-client-lib">https://github.com/bloxbean/cardano-client-lib</a></li><li>Cardano Client Lib Docs — <a href="https://cardano-client.dev">https://cardano-client.dev</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5beb491282ce" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cardano Mempool monitoring with Yaci Java Library]]></title>
            <link>https://satran004.medium.com/cardano-mempool-monitoring-with-yaci-java-library-1fef73bc4406?source=rss-3bb19096c001------2</link>
            <guid isPermaLink="false">https://medium.com/p/1fef73bc4406</guid>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[cardano]]></category>
            <category><![CDATA[yaci]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[cardano-client-lib]]></category>
            <dc:creator><![CDATA[Satya]]></dc:creator>
            <pubDate>Mon, 12 Dec 2022 15:20:46 GMT</pubDate>
            <atom:updated>2022-12-12T15:44:05.596Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QLfVWh0-3u12jYEI9meh4w.png" /></figure><p>In this post, I am going to explain how to monitor a local Cardano node’s mempool using Java or any JVM language. To do that we are going to use a small Java library called “<a href="https://github.com/bloxbean/yaci">Yaci</a>” and we need an instance of Cardano node.</p><h3>What’s Yaci ?</h3><p>An opensource project which implements Cardano mini-protocol.</p><p>Mini-protocols are a set of protocols which are used to enable communication between different Cardano nodes. These protocols can also be used by other client applications like indexer, explorer, wallets to fetch data from a node and create their own data store. There are two categories: node-to-node and node-to-client. The node-to-client protocol suite is mostly for trusted clients like wallets and chain consumers.</p><p>Yaci implements most of the mini protocols including local transaction submission.</p><p>To find the list of mini-protocols currently supported by Yaci, please visit project’s GitHub page.</p><p><a href="https://github.com/bloxbean/yaci#status">https://github.com/bloxbean/yaci#status</a></p><p>To simplify the usage of mini protocol, it also provides various high level apis for different scenarios. So Java developers don’t need to understand the low level protocol details. There are two types of high level apis</p><ul><li><strong>Listener based</strong></li></ul><p>Using listener based apis, you can easily get callbacks for different events like new blocks, rollback etc.</p><ul><li><strong>Reactive apis using</strong> <a href="https://projectreactor.io/">https://projectreactor.io/</a></li></ul><p>Using reactive apis, you can receive blocks data through a Flux and can compose functionalities using available operators like filter, map etc.</p><p><strong>Usage Scenarios Examples :</strong></p><p>The followings are few examples where Yaci can be used</p><ul><li>To listen real-time events from a node (Example: Token minting, Token minted for a policy, Transactions …)</li><li>Receive block/transaction data and create your own data store or query layer</li><li>Alert or notification based on events in blockchain</li><li>Create your own indexer</li><li>Implement a Tx submission service by submitting transactions to a local Cardano node or a remote node with node-to-client protocol exposed through a relay like “socat”</li></ul><h3>Mempool monitoring</h3><p>As mentioned earlier, we will go through the steps required for local mempool monitoring.</p><p><strong>Pre-requisites</strong></p><ol><li>Local Tx Monitor is a node-to-client protocol. Node-to-client protocols are exposed through Unix domain socket. So that a local trusted client can connect and access those info from Cardano node. But you can use a relay like “socat” to expose Unix domain socket through a TCP socket for remote clients.</li></ol><p><strong>Example :</strong></p><pre>socat TCP-LISTEN:31001,fork UNIX-CONNECT:/data/cardano/pre-prod/db/node.socket</pre><p>The apis for local tx monitoring in yaci accepts both path host / port and local socket file.</p><p>2. Create a Java app and add Yaci dependency to it</p><pre>&lt;dependency&gt;<br>     &lt;groupId&gt;com.bloxbean.cardano&lt;/groupId&gt;<br>     &lt;artifactId&gt;yaci&lt;/artifactId&gt;<br>     &lt;version&gt;0.1.2&lt;/version&gt;<br>&lt;/dependency&gt;</pre><p><strong>Note:</strong> Get the latest released version of Yaci from project’s <a href="https://github.com/bloxbean/yaci">GitHub</a>.</p><p>As we will be getting transaction bytes from the mempool, we will use “<strong>cardano-client-lib</strong>” to get transaction hash and to de-serialize transaction. This is only required for our example.</p><pre>&lt;dependency&gt;<br>      &lt;groupId&gt;com.bloxbean.cardano&lt;/groupId&gt;<br>      &lt;artifactId&gt;cardano-client-lib&lt;/artifactId&gt;<br>      &lt;version&gt;0.4.0&lt;/version&gt;<br>&lt;/dependency&gt;</pre><h4>Configure and start the connection</h4><p>First we need to setup the connection to a Cardano node through node-to-client protocol. So let’s get the path to Cardano’s<strong> nodeSocketFile</strong> and network’s <strong>protocol magic</strong>.</p><pre> String nodeSocketFile = &quot;~/cardano-node/preprod/db/node.socket&quot;;<br> long protocolMagic = Constants.PREPROD_PROTOCOL_MAGIC;</pre><p><strong>Note:</strong> You can use <em>com.bloxbean.cardano.yaci.core.common.Constant</em> class to get protocol magics for public networks.</p><blockquote>Alternatively, if the node-to-client protocol is exposed through a relay like “socat”, get host and port.</blockquote><p>Now, create an instance of <em>LocalClientProvider</em> and start the client.<br>As <em>LocalClientProvider</em> supports both <strong>local state query</strong> and <strong>local tx monitor</strong> mini protocols, you can now execute supported queries on a node.</p><pre> LocalClientProvider localClientProvider = new LocalClientProvider(nodeSocketFile, protocolMagic);<br> localClientProvider.start();</pre><p>In the above code snippet, we are creating a local client and then starting the client.</p><p>Let’s get “<em>LocalTxMonitorClient</em>” from <em>localClientProvider</em>.</p><pre>LocalTxMonitorClient localTxMonitorClient = localClientProvider.getTxMonitorClient();</pre><p>Now we are ready to query the node.</p><h4><strong>Query Mempool Transactions</strong></h4><p>To get the list of transactions currently in the mempool, we need to first acquire a mempool snapshot and then query the snapshot. You can acquire and query in two method calls or just use “<strong>acquireAndGetMempoolTransactionsAsMono()” </strong>which wraps both steps in one method call.</p><p>In this example, let’s monitor the mempool in a loop. Acquire method is a blocking call, so the program waits there till the availability of new snapshot.</p><pre>while (true) {<br>     // local tx monitor code<br>}</pre><p>Let’s add the following code snippets in the above while(true) loop.</p><pre>List&lt;byte[]&gt; txBytesList = localTxMonitorClient.acquireAndGetMempoolTransactionsAsMono().block();</pre><p>The above code will acquire a new snapshot when available and return a list of transactions as bytes in a <strong>Mono</strong>. We are using “<strong>block()</strong>” to get the list of transactions through a blocking call. <br><strong>Note:</strong> You should use Mono’s non-blocking api like “subscribe” in your application to avoid blocking.</p><p>Now that we have a list of transactions as bytes, we can loop through the list to get transaction hashes and de-serialize available transactions. This can be easily done using <a href="https://github.com/bloxbean/cardano-client-lib">Cardano Client Lib</a>.</p><pre>for(byte[] txBytes: txBytesList) {<br>    String txHash = TransactionUtil.getTxHash(txBytes);<br>    System.out.println(&quot;Tx Hash &gt;&gt; &quot; + txHash);<br><br>    Transaction transaction = Transaction.deserialize(txBytes);<br>    System.out.println(&quot;Tx Body &gt;&gt; &quot; + transaction);<br>}</pre><p>Finally, let’s get the mempool size and capacity. Local tx monitor also provides information like mempool capacity, size and no of txs.</p><p>The following code snippet is getting the mempool status. You can see that we are using “<strong>getMempoolSizeAndCapacity()</strong>” in the below code snippet. This method doesn’t acquire a new snapshot and it uses the already acquired snapshot in the previous call.<br>But if you want to acquire a new snapshot and query mempool status, then you can use “<strong>acquireAndGetMempoolSizeAndCapacity()</strong>”.</p><pre>MempoolStatus mempoolStatus = localTxMonitorClient.getMempoolSizeAndCapacity().block();<br>System.out.println(&quot;Mem Pool &gt;&gt; &quot; + mempoolStatus);</pre><p>Our mempool monitoring app is now ready. Run this program and then submit few transactions to this node through another program or Cardano CLI, you should start seeing the transactions as soon as those are available in mempool.</p><p><strong>Sample Output:</strong></p><pre>Waiting to acquire next snapshot ...<br>Mem Pool &gt;&gt; MempoolStatus(capacityInBytes=178176, sizeInBytes=0, numberOfTxs=0)<br>Waiting to acquire next snapshot ...<br>Tx Hash &gt;&gt; 4d7ce3ece2f9aa36550763753df3885344b1f15ea1e67dd7c9f3f49924f0f480<br>Tx Body &gt;&gt; Transaction(body=TransactionBody(inputs=[TransactionInput{transactionId=7e36a90a9b85902d5b42599f831d...<br>Waiting to acquire next snapshot ...</pre><p>That’s it. We covered only one use case in this post, but Yaci provides different apis which can support many different types of use cases.</p><p>Here’s a list of few major high level apis in Yaci that you may find interesting</p><ul><li><strong>BlockStreamer</strong> <strong>:</strong> Reactive api to start getting blocks from current tip or from a given point.</li><li><strong>BlockSync :</strong> Get latest block data starting from current tip through a listener.</li><li><strong>BlockRangeSync : </strong>Get blocks data from point-1 to poin-2 through a listener</li><li><strong>LocalTxSubmissionClient :</strong> To submit a transaction to Cardano node</li><li><strong>TipFinder</strong> <strong>: </strong>To find the tip through a simple method call</li></ul><p><a href="https://gist.github.com/satran004/b33b181c020113113f5976c562b1278b"><strong>Full source code of mempool monitoring example</strong></a></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0ced605dc81a354fcae2bd5bec034b2b/href">https://medium.com/media/0ced605dc81a354fcae2bd5bec034b2b/href</a></iframe><p><strong><em>References:</em></strong><br><strong>1. Yaci :</strong> A Cardano Mini Protocols implementation in Java <a href="https://github.com/bloxbean/yaci">(https://github.com/bloxbean/yaci</a>)</p><p><strong>2. Cardano Client Lib :</strong> Cardano client library in Java (<a href="https://github.com/bloxbean/cardano-client-lib">https://github.com/bloxbean/cardano-client-lib</a>)</p><p><strong>3. Yaci CLI : </strong>A CLI example using Yaci (<a href="https://github.com/bloxbean/yaci-cli">https://github.com/bloxbean/yaci-cli</a>)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1fef73bc4406" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Call Plutus V2 contract from off-chain Java code using Cardano Client Lib]]></title>
            <link>https://satran004.medium.com/call-plutus-v2-contract-from-off-chain-java-code-using-cardano-client-lib-e2b7e1b27c4?source=rss-3bb19096c001------2</link>
            <guid isPermaLink="false">https://medium.com/p/e2b7e1b27c4</guid>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[smart-contracts]]></category>
            <category><![CDATA[plutus]]></category>
            <category><![CDATA[cardano]]></category>
            <category><![CDATA[java]]></category>
            <dc:creator><![CDATA[Satya]]></dc:creator>
            <pubDate>Fri, 29 Jul 2022 18:03:33 GMT</pubDate>
            <atom:updated>2022-07-29T18:03:33.587Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ckKkMAT9B-v2QtgSs4qe9g.png" /></figure><p>In this post, we will go through the steps required to invoke a <a href="https://developers.cardano.org/docs/smart-contracts/plutus/">Plutus</a> smart contract from a Java application using Cardano Client Lib.</p><blockquote><a href="https://github.com/bloxbean/cardano-client-lib"><strong>Cardano-client-lib</strong></a> is a Java client library for <a href="https://cardano.org/"><strong>Cardano</strong></a> blockchain. It simplifies the interaction with Cardano blockchain from Java applications. Using this library, you can perform various types of transactions including smart contract calls in a Java application.</blockquote><p><strong>Compatible version: </strong>Cardano Client Lib 0.3.0-beta2 and above</p><h4><strong>Plutus Contract Example</strong></h4><p>We will use a simple contract called <em>“Sum Contract”</em> as an example in this post. To validate, the sum contract checks the sum of 0..n, where n is the datum value. The caller can unlock the fund in a script output by guessing the correct sum.</p><p>While this is a very simple plutus contract, but through this example we will try to use some of the new exciting features available in Babbage era (after Vasil Hardfork).</p><ol><li>Reference Inputs (<a href="https://cips.cardano.org/cips/cip31/">CIP 31</a>)</li><li>Inline Datums (<a href="https://cips.cardano.org/cips/cip32/">CIP 32</a>)</li><li>Reference Scripts (<a href="https://cips.cardano.org/cips/cip33/">CIP 33</a>)</li><li>Collateral Output (<a href="https://cips.cardano.org/cips/cip40/">CIP 40</a>)</li></ol><p>So, in high level we will be going through the following steps :</p><ol><li><strong>Create a reference script output to attach a script to the output.</strong> This is part of <a href="https://cips.cardano.org/cips/cip33/">CIP 33</a>. With reference script output, we don’t need to send the script body in the spending transaction.</li><li><strong>Send some fund to script address with inline datum.</strong> The fund will be locked in the script output. Inline datum is defined in <a href="https://cips.cardano.org/cips/cip32/">CIP 32</a>. So instead of storing datum hash, we can now store datum value directly in the output.</li><li><strong>Finally, create a spending transaction to unlock fund in script output.</strong> In spending transaction, we will refer to the reference script output (step-1) as a reference input. This is part of <a href="https://cips.cardano.org/cips/cip31/">CIP 31</a>. Also, we are going to use collateral outputs (<a href="https://cips.cardano.org/cips/cip40/">CIP 40</a>) in the spending transaction.</li></ol><p>Before going through our example, let’s discuss some basic concepts in Cardano Client Lib. For more details, you can check my previous posts.</p><p>Alternatively, you can jump to the section “<strong>Invoke Guess Sum Contract</strong>” if you are already aware of these concepts.</p><h3>Composable Functions</h3><p>A set of <em>FunctionalInterface</em> which can be used to implement composable functions. These functions are used to build various different types of transactions. The library provides many useful out-of-box implementations of these functions. Most of the commonly used functions are already there. If required, application developers can write their own functions and use them with other out of box functions.</p><p>The followings are the main <em>FunctionalInterface</em></p><ol><li><strong>TxBuilder</strong></li><li><strong>TxOutputBuilder</strong></li><li><strong>TxInputBuilder</strong></li><li><strong>TxSigner</strong></li></ol><p><strong>TxBuilder :</strong> This functional interface helps to transform a transaction object. The apply method in this interface takes a <em>TxBuilderContext</em> and a <em>Transaction</em> object as input parameters. The role of this function is to transform the input transaction object with additional attributes or update existing attributes.</p><p><strong>TxOutputBuilder :</strong> This functional interface helps to build a <em>TransactionOutput</em> object and adds that to the transaction output list. The <em>accept</em> method in this interface takes a <em>TxBuilderContext</em> and a list of <em>TransactionOutput</em>.</p><p><strong>TxInputBuilder :</strong> This functional interface is responsible to build inputs for the expected outputs.</p><p><strong>TxSigner :</strong> This interface is responsible to provide transaction signing capability.</p><h3><strong>Backend Service and Supplier Interfaces</strong></h3><p>The library provides a backend service layer, which is required to build and submit transaction to Cardano blockchain. By default, it provides backend service implementations for Blockfrost, Koios etc.</p><p>But, if you want to use some other providers to build and submit transaction, you can easily do so by implementing following three simple interfaces :</p><ol><li><strong>ProtocolParameterSupplier :-</strong> Implement this functional interface to provide current protocol parameters. Protocol parameters are required to build the transaction.</li></ol><pre>public interface ProtocolParamsSupplier {<br>    ProtocolParams getProtocolParams();<br>}</pre><p>2.<strong> UtxoSupplier:-</strong> This interface has only one method. Implement this interface to provide utxos which are required during transaction building.</p><p>3. <strong>TransactionProcessor :- </strong>Implement this interface to submit transaction to the Cardano blockchain.</p><pre>public interface TransactionProcessor {<br><br>    Result&lt;String&gt; submitTransaction(byte[] cborData) throws ApiException;<br>}</pre><p><strong>Note:</strong> If you are using a supported backend provider like <a href="https://blockfrost.io/">Blockfrost</a>, you can just use the out-of-box backend service implementation.</p><h3>Invoke Guess Sum Contract</h3><p>In this section, we will go through the example step by step. You can also find the full source code of the example <a href="https://github.com/bloxbean/cardano-client-examples/blob/6a4008ae361cafac7f35276621bc57feb2a61eb9/src/test/java/com/bloxbean/cardano/client/example/function/contract/v2/GuessSumContractTest.java">here</a>.</p><p>Now, let’s start with some initialization steps.</p><h4><strong>Account setup</strong></h4><p>To submit any transaction to Cardano blockchain, we need an account to sign and pay transaction fee.</p><p>So, let’s see how to create a sender account object from a mnemonic phrase. We will be using this account to send fund to the script output and also to unlock the fund.</p><pre>String senderMnemonic = &quot;&lt;24 words mnemonic phrase&gt;&quot;;</pre><pre>Account sender = new Account(Networks.<em>testnet</em>(), senderMnemonic);</pre><pre>String senderAddress = sender.baseAddress();</pre><h4><strong>Plutus V2 Script Object and Script address</strong></h4><p>We need to use the compiled version of our <em>Sum contract</em> script. The following code snippet shows how to initialize the PlutusV2Script instance and find the script address.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/21dd14fc6c3b2f03d738076ccbe39e47/href">https://medium.com/media/21dd14fc6c3b2f03d738076ccbe39e47/href</a></iframe><h4>1. Create a reference script output</h4><p>Now that we have an account and a script instance, we can build and submit a transaction to create a reference script output. The script body will be stored in the output on-chain.</p><blockquote><strong><em>Let’s first start with the expected output.</em></strong></blockquote><p>We want to create an output with script reference. For simplicity, we can set the lovelace amount in the output to 0. The library will automatically calculate the min required ada and set it accordingly. You can also see the sumScript is passed as parameter in scriptRef().</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5394db09ad7450f8e8c6a7c70c5fb7c6/href">https://medium.com/media/5394db09ad7450f8e8c6a7c70c5fb7c6/href</a></iframe><blockquote><strong><em>Now with the above expected output, let’s create an instance of TxBuilder using composable functions.</em></strong></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1a47b277c394c2bf0b3941d88a6f54b0/href">https://medium.com/media/1a47b277c394c2bf0b3941d88a6f54b0/href</a></iframe><p>In the above code snippet, we are getting <em>TxOutputBuilder</em> from the expected output (<em>scriptRefOutput</em>) and then using <em>createFromSender </em>composable function, we are creating <em>TxInputBuilder</em> and finally, <em>buildInputs </em>method is using <em>TxInputBuilder</em> to return <em>TxBuilder</em>.</p><p>So in summary, we selected required <em>TransactionInputs</em> for our expected output.</p><p>In <strong>Line-3</strong>, we are using another composable function “<em>balanceTx</em>” to balance the transaction. This is a wrapper function which calls other low level functions like <em>feeCalculation</em>, <em>changeOutputAdjustment</em> to balance an unbalanced transaction. The “<em>balanceTx</em>” function takes two parameters, change address and no of signers.</p><blockquote><strong><em>Now, we can build the transaction using TxBuilder and submit it to Cardano network.</em></strong></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/15a7c8ff71b9c2ca6a6f456a21217056/href">https://medium.com/media/15a7c8ff71b9c2ca6a6f456a21217056/href</a></iframe><p>In <strong>Line-1</strong>, <em>a TxBuilderContext</em> is created using <em>UtxoSupplier</em> and <em>ProtocolParamsSupplier </em>as parameters. If you are using <em>Blockfrost </em>or <em>Koios</em> as provider, these implementation are provided out-of-box. But you can easily provide your own supplier implementations if required.</p><p>In <strong>Line-2</strong>, <em>TxBuilderContext’s</em> <strong><em>buildAndSign</em></strong><em> </em>method is used to build and sign the transaction by applying the previously created <em>TxBuilder</em> instance (<em>scriptRefTxBuilder</em>) and the <em>TxSigner</em> instance for sender.</p><p>In <strong>Line-4</strong>, the signed transaction is then submitted through the backend service’s <em>TransactionService</em> implementation. Alternatively, you can use your own <em>TransactionProcessor</em> implementation to submit the transaction.</p><p>That’s it. Now we have an output with script body as script reference.</p><h4>2. Send fund to script address with inline datum</h4><p>Now it’s time to send some fund to the script address that we had generated earlier using the PlutusV2Script instance. We will set an integer as datum value for the output. But instead of setting datum hash, the datum value will be directly stored in the output.</p><blockquote><strong>This is a simple transaction like step-1 but with inline datum.</strong></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f002def4821a81f76ba5a6e72bea82f8/href">https://medium.com/media/f002def4821a81f76ba5a6e72bea82f8/href</a></iframe><p><strong>In Line-1</strong>, we are creating an integer type Plutus data which is used as inline datum. The datum value is 8.</p><p><strong>In Line-3 to Line-8,</strong> the expected output is defined with the inline datum (8).</p><p><strong>Line-10 to Line 17</strong> are similar to<strong> step-1</strong>, where a transaction is built and signed by <em>TxBuilder</em>, <em>TxBuilderContext</em> and finally submitted through <em>TransactionService</em>.</p><p>Now, we have an output at the script address with some locked fund (4 ADA) .</p><p>In the next section, we are going to create a spending transaction to unlock the fund.</p><h4>3. Create a spending transaction (script txn) to spend the locked fund</h4><blockquote><strong>To spend the locked fund, let’s first find the output at the script address.</strong></blockquote><p>You can use one of the helper method in <em>ScriptUtxoFinders</em> class to find the required output.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/246d5ca3e6c8cfb9992b588c7f2b8e09/href">https://medium.com/media/246d5ca3e6c8cfb9992b588c7f2b8e09/href</a></iframe><p><strong>In Line-1,</strong> we find the output using datum.</p><p><strong>In Line-2 to Line-5,</strong> we are trying to find the claim amount from the output. It’s basically the lovelace value in this example.</p><blockquote><strong>Now, it’s time to find some collateral for our script transaction.</strong></blockquote><p>In Babbage era (after Vasil HF), we can also use an utxo with native tokens as collateral. The remaining lovelace amount and native tokens are sent back as collateral output. You can find more details about collateral outputs spec in <a href="https://cips.cardano.org/cips/cip40/">CIP 40</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f0e949490c50381e7288c6443a66617f/href">https://medium.com/media/f0e949490c50381e7288c6443a66617f/href</a></iframe><p>In the above code snippet, we are using <em>UtxoSelectionStrategy</em> to find an utxo with minimum 5 ADA for the collateral input. In this case, we are using <em>LargestFirstUtxoSelectionStrategy</em> implementation, but you can also use other implementations like <em>DefaultUtxoSelectionStrategyImpl</em> or <em>RandomImproveSelectionStrategy</em>.</p><p>Alternatively, you can also use <em>DefaultUtxoSelector </em>class by providing a predicate.</p><blockquote><strong>Now, let’s define the expected output and create a script call context.</strong></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/86eef3a643f4141cb847eadc1327eb72/href">https://medium.com/media/86eef3a643f4141cb847eadc1327eb72/href</a></iframe><p><strong>Line-1 to Line-5,</strong> define an expected output with the claim amount and a receiver address.</p><p><strong>In Line-7 to Line-8,</strong> we are creating a <em>ScriptCallContext</em> with all required data like script object, redeemer details and exunits.</p><p>Note that the redeemer value is set to 36 as the sum of our datum (0..8) is 36.<br>ExUnits value is set to 0 as we are going to evaluate the actual script cost later.</p><p>Also, we are not providing datum value as our script output has inline datum instead of datum hash.</p><blockquote><strong>Now we are ready to create our TxBuilder instance and then create &amp; sign the transaction and finally submit to the Cardano network to unlock the locked value.</strong></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e29d3e4eb171fba2133cc0c69dc3ce80/href">https://medium.com/media/e29d3e4eb171fba2133cc0c69dc3ce80/href</a></iframe><p><strong>Line-1 &amp; Line-2 :</strong> Use the expected output and create inputs from script utxo that we found in one of the previous step.</p><p><strong>Line-3 :</strong> Add <em>reference script output</em> (from <strong>step-1</strong>) as <em>reference input</em>. This is part of <a href="https://cips.cardano.org/cips/cip31/">CIP 31</a>.</p><p><strong>Line-4 :</strong> Create <em>collateral and collateral outputs</em> using collateral utxos. The sender address is used as change address for <em>collateral outputs</em>.</p><p><strong>Line-5: </strong>Use <em>ScriptCallContext</em> instance that we created before to populate script call related attributes in the transaction.</p><p><strong>Line-6 to Line-15 : </strong>Evaluate exact ExUints by invoking evaluateTx() of backend service. This can also be done as a separate step before building of transaction. But, please make sure it’s done before fee calculation or before balanceTx method call.</p><p><strong>Line-22 to Line-28 :</strong> Now as usual, build the transaction and submit it to Cardano network.</p><p>That’s it. We successfully invoked our on-chain plutus contract from off-chain Java code using Cardano Client Lib.</p><p><a href="https://github.com/bloxbean/cardano-client-examples/blob/6a4008ae361cafac7f35276621bc57feb2a61eb9/src/test/java/com/bloxbean/cardano/client/example/function/contract/v2/GuessSumContractTest.java">Full source code</a></p><p>For more examples, you can check Cardano Client Example <a href="https://github.com/bloxbean/cardano-client-examples/">GitHub repo</a>.</p><h4>Resources</h4><ol><li><a href="https://github.com/bloxbean/cardano-client-lib">Cardano Client Lib GitHub Repo</a></li><li><a href="https://github.com/bloxbean/cardano-client-examples/">Cardano Client Example Repo</a></li><li><a href="https://medium.com/coinmonks/cardano-client-lib-new-composable-functions-to-build-transaction-in-java-part-i-be3a8b4da835">New Composable functions to build transaction</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e2b7e1b27c4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cardano-client-lib: New composable functions to build transaction in Java— Part I]]></title>
            <link>https://medium.com/coinmonks/cardano-client-lib-new-composable-functions-to-build-transaction-in-java-part-i-be3a8b4da835?source=rss-3bb19096c001------2</link>
            <guid isPermaLink="false">https://medium.com/p/be3a8b4da835</guid>
            <category><![CDATA[cardano]]></category>
            <category><![CDATA[cardano-client-lib]]></category>
            <category><![CDATA[smart-contract-blockchain]]></category>
            <category><![CDATA[cryptocurrency]]></category>
            <category><![CDATA[blockchain]]></category>
            <dc:creator><![CDATA[Satya]]></dc:creator>
            <pubDate>Sun, 27 Feb 2022 16:37:23 GMT</pubDate>
            <atom:updated>2022-10-05T15:12:07.715Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jnoVnR0NunTIJb0ug7qPeQ.png" /></figure><p><a href="https://github.com/bloxbean/cardano-client-lib"><strong>Cardano-client-lib</strong></a> is a Java client library for <a href="https://cardano.org/"><strong>Cardano</strong></a> blockchain. It simplifies the interaction with Cardano blockchain from a Java application. Using this library, you can perform various types of transactions in a Java application.</p><p>For example, you can do a transfer from one address to another, mint a token or an NFT and invoke a Plutus smart contract in Java.</p><p>In this post, I am going to explain the concept of newly introduced composable functions API.</p><blockquote><em>In the next few posts of this series, I will go through specific examples from regular transfer to token minting to plutus contract calls using composable function apis.</em></blockquote><p>If you are new to <strong>cardano-client-lib</strong>, it currently supports three types of apis to build / perform various transactions.</p><ol><li><strong>High Level API : </strong>Provides simple interfaces to do transfer and token minting transaction. But some complex transactions may not be possible through high-level API.</li><li><strong>Low Level API : </strong>These are low level serialization api to build transaction for Cardano network. These APIs are flexible and good for complex scenarios. Basically, you can achieve any complexity with low level api, but at the same time these APIs are not beginner friendly.</li><li><strong>Composable Functions :</strong> These APIs were introduced in v0.2.0-beta2 which provide a balance between simple interface and flexibility. Using <strong>out-of-box </strong>composable functions, you can achieve any complexity and at the same time, you can write your own composable functions to customize the behavior during transaction building.</li></ol><p>So in this post, I am going to focus on the general concepts of composable functions in the library.</p><h3><strong>Composable Functions</strong></h3><p>The current version of the library provides a set of <em>FunctionalInterface</em> which can be used to implement composable functions. These functions can be used to build various different types of transactions. The library provides many useful out-of-box implementations of these functions.</p><p>The followings are the main <em>FunctionalInterface</em></p><ol><li><strong>TxBuilder</strong></li><li><strong>TxOutputBuilder</strong></li><li><strong>TxInputBuilder</strong></li><li><strong>TxSigner</strong></li></ol><p><strong>TxBuilder :</strong> This functional interface helps to transform a transaction object. The build method in this interface takes a <em>TxBuilderContext</em> and a <em>Transaction</em> object as input parameters. The role of this function is to transform the input transaction object with additional attributes or update existing attributes.</p><p><strong>TxOutputBuilder :</strong> This functional interface helps to build a <em>TransactionOutput</em> object and add that to the transaction output list. The <em>accept</em> method in this interface takes a <em>TxBuilderContext</em> and a list of <em>TransactionOutput</em>.</p><p><strong>TxInputBuilder :</strong> This functional interface is responsible to build inputs from the expected outputs.</p><p><strong>TxSigner :</strong> This interface is responsible to provide transaction signing capability.</p><h3><strong>TxBuilderContext</strong></h3><p>Each function takes <em>TxBuilderContext</em> as the first input parameter. The main responsibility of <em>TxBuilderContext</em> is to provide context data like <em>UtxoSupplier</em>, <em>ProtocolParamsSupplier, UtxoSelectionStrategy</em> and some temporary data to the functions during the transaction building.</p><h3><strong>Function Helpers</strong></h3><p>The library provides many <strong>out-of-box</strong> functions through helper classes which help to build the transaction. So you don’t need to start from zero and the same time you can write your own functions if required.</p><p>In the current version of the library, the following helper classes are available</p><ol><li><strong>OutputBuilders : </strong>Provides a list of helper methods to create a <em>TxOutputBuilder</em> function which is used create a <em>TransactionOutput</em> from a <em>TransactionOutput</em> or <em>Output </em>object. The <em>TxOutputBuilder</em> functions verify min ada requirement and update the ada amount accordingly in the <em>TransactionOutput</em>.</li></ol><p>Some of the helper methods available in this class are</p><pre><em>- </em>TxOutputBuilder createFromOutput(Output output)<br></pre><pre>- TxOutputBuilder createFromOutput(TransactionOutput txnOutput)<br></pre><pre>- TxOutputBuilder createFromMintOutput(Output output)<br></pre><pre>- TxOutputBuilder createFromMintOutput(TransactionOutput txnOutput)</pre><p>You can combine multiple <em>TxOutputBuilder</em> using “<strong><em>and</em></strong>” method.</p><pre>TxOutputBuilder txOutputBuilder = <strong>createFromOutput(output1)<br>                                     .and(createFromOutput(output2))</strong></pre><blockquote><strong>Note:</strong> For token minting transaction, to calculate min required ada in output accurately, mint outputs or createFromMintOutput() methods should be invoked after all regular outputs or createFromOutput() methods.</blockquote><p>2. <strong>InputBuilders :</strong> Provides helper methods to create a <em>TxInputBuilder</em> function which is used to build required <em>TransactionInput</em>(s) from a list of <em>TransactionOutput</em>(s) using <em>buildInputs</em>() method of <em>TxOutputBuilder</em>.</p><pre>TxBuilder txBuilder = txOutputBuilder1<br>                       .and(txOutputBuilder2)<br>                       <strong>.buildInputs(createFromSender(senderAddress, changeAddress))</strong></pre><p>Some of the helper methods available in this class are</p><pre>- TxInputBuilder createFromSender(String sender, String changeAddress)<br></pre><pre>- TxInputBuilder createFromUtxos(List&lt;Utxo&gt; utxos)<br></pre><pre>- TxInputBuilder createFromUtxos(Supplier&lt;List&lt;Utxo&gt;&gt; supplier)<br></pre><pre>- TxInputBuilder createFromUtxos(List&lt;Utxo&gt; utxos, String changeAddress)<br></pre><pre>- TxInputBuilder createFromUtxos(List&lt;Utxo&gt; utxos, String changeAddress, Object datum)<br></pre><pre>- TxInputBuilder createFromUtxos(List&lt;Utxo&gt; utxos, String changeAddress, String datumHash)</pre><p>3.<strong> MintCreators :</strong> It provides helper methods to create a <em>TxBuilder</em> function which is used to add multiasset minting related data to the <em>Transaction</em> object.</p><pre>TxBuilder txBuilder = txOuputBuilder1<br>                        .and(txOuputBuilder2)<br>                        .and(createFromMintOutput(mintOutput))<br>                      .buildInputs(txInputBuilder)<br>                     <strong> .andThen(mintCreator(script, multiAsset)</strong></pre><blockquote><strong>Note:</strong> For minting transaction, a TxOutputBuilder specific to mint output is required. This can be done by calling one of the OutputBuilders.createFromMintOutput method.</blockquote><p>Some of the helper methods available in this class are</p><pre>- TxBuilder mintCreator(Script script, MultiAsset multiAsset)<br></pre><pre>- TxBuilder mintCreator(Script script, MultiAsset multiAsset, boolean inclScriptInAuxData)<br></pre><p>4. <strong>AuxDataProviders :</strong> Provides helper methods to create a <em>TxBuilder</em> function which is used to add metadata to the <em>Transaction</em> object.</p><pre>TxBuilder txBuilder = txOuputBuilder1<br>                        .and(txOuputBuilder2)<br>                      .buildInputs(txInputBuilder)<strong><br>                      .andThen(<em>metadataProvider</em>(metadata))</strong></pre><p>5. <strong>CollateralBuilders :</strong> Provides helper methods to create a <em>TxBuilder</em> function which is used to add collateral(s) to the <em>Transaction</em> object in a plutus script transaction.</p><pre>TxBuilder txBuilder = txOuputBuilder1<br>                        .and(txOuputBuilder2)<br>                      .buildInputs(txInputBuilder)<br>                      <strong>.andThen(<em>collateralFrom</em>(txHash, txIndex))</strong></pre><p>Some of the helper methods available in this class are</p><pre>- TxBuilder collateralFrom(String txHash, int txIndex)<br></pre><pre>- TxBuilder collateralFrom(List&lt;Utxo&gt; utxos)<br></pre><pre>- TxBuilder collateralFrom(Supplier&lt;List&lt;Utxo&gt;&gt; supplier)</pre><p>6. <strong>ScriptCallConextProviders :</strong> Provides helper methods to create a <em>TxBuilder</em> function which is used to add plutus script specific data to a <em>Transaction</em> object.</p><pre>TxBuilder txBuilder = txOuputBuilder1<br>              .and(txOuputBuilder2)<br>           .buildInputs(txInputBuilder)<br>           .andThen(collateralFrom(txHash, txIndex))<br>           <strong>.andThen(createFromScriptCallContext(scriptCallContext))</strong></pre><p>Some of the helper methods available in this class are</p><pre>- TxBuilder createFromScriptCallContext(ScriptCallContext sc)<br></pre><pre>- TxBuilder scriptCallContext(PlutusScript plutusScript, Utxo utxo,              T datum, K redeemerData,RedeemerTag tag, ExUnits exUnits)<br></pre><pre>- TxBuilder scriptCallContext(PlutusScript plutusScript, int scriptInputIndex, T datum, K redeemerData, RedeemerTag tag, ExUnits exUnits)</pre><p>7. <strong>FeeCalculators :</strong> Provides helper methods to create <em>TxBuilder</em> function to calculate fee and update <em>Transaction</em> object accordingly.</p><pre>TxBuilder txBuilder = txOuputBuilder1<br>                        .and(txOuputBuilder2)<br>                      .buildInputs(txInputBuilder)<br>                      .andThen(otherTxBuilder)<br>                      ...<br>                      <strong>.andThen(feeCalculator(changeAddress, noOfSigners))</strong></pre><blockquote><strong>Note: </strong>No of signers is required to calculate the fee accurately. For example, for a minting transaction with a policy script, min no of signers is 2. (Minting account, Policy script secret key)</blockquote><p>Helper methods to create <em>TxBuilder</em> function in this helper class are</p><pre>- TxBuilder feeCalculator(String changeAddress, int noOfSigners)<br></pre><pre>- TxBuilder feeCalculator(int noOfSigners, UpdateOutputFunction updateOutputWithFeeFunc)</pre><p>8. <strong>ChangeOutputAdjustments :</strong> Provides helper methods to create <em>TxBuilder</em> function which can adjust the change output. This function is used to verify if the ada amount in change output satisfies min ada requirement. If not, it tries to get additional inputs and adjust the change output after the fee calculation. This function is used after <em>feeCalculation</em> function.</p><pre>TxBuilder txBuilder = txOuputBuilder1<br>             .and(txOuputBuilder2)<br>             .buildInputs(txInputBuilder)<br>             .andThen(otherTxBuilder)<br>             ...<br>             .andThen(feeCalculator(changeAddress, noOfSigners))<br>             <strong>.andThen(<em>adjustChangeOutput</em>(senderAddress, changeAddress, noOfSigners))</strong></pre><p>9. <strong>SignerProviders : </strong>Provides helper methods to create <em>TxSigner</em> function to sign a transaction.</p><pre>TxSigner signer = <em>signerFrom</em>(sender1, sender2, ..., sendern)<br>                   .andThen(signerFrom(secretKey1, ..., secretKeyn))</pre><p>Some of the helper methods available in this class are</p><pre>- TxSigner signerFrom(Account... signers)</pre><pre>- TxSigner signerFrom(SecretKey... secretKeys)</pre><pre>- TxSigner signerFrom(Policy... policies)</pre><p>10. <strong>MinAdaCheckers :</strong> Provides a helper method to return <em>MinAdaChecker</em> function. <em>MinAdaChecker</em> function returns the additional lovelace amount required for a <em>TransactionOutput</em> to meet the min ada requirement. This function is used internally by implementations of other functions. You may not need to use this function directly.</p><h3><strong>Build and Sign Transaction</strong></h3><p>After <em>TxBuilder</em> is created by composing different functions, a <em>Transaction </em>object can be built and signed.</p><pre>TxBuilder txBuilder = <em>createFromOutput</em>(output)<br>        .buildInputs(<em>createFromSender</em>(senderAddress, senderAddress))<br>        .andThen(<em>metadataProvider</em>(metadata))<br>        .andThen(<em>feeCalculator</em>(senderAddress, 1))<br>        .andThen(<em>adjustChangeOutput</em>(senderAddress, 1));</pre><pre>TxSigner signer = SignerProviders.signerFrom(sender);</pre><pre><strong>/*** Create instance of UtxoSupplier &amp; ProtocolParamsSupplier ***/<br></strong>UtxoSupplier utxoSupplier = new         DefaultUtxoSupplier(backendService.getUtxoService());</pre><pre>ProtocolParamsSupplier protocolParamsSupplier = new DefaultProtocolParamsSupplier(backendService.getEpochService());</pre><pre><strong>/**** Build and Sign in one step ****/</strong><br>Transaction signedTxn = <br>     TxBuilderContext.<em>init</em>(utxoSupplier, protocolParamsSupplier)<br>           .buildAndSign(txBuilder, signer);</pre><pre><strong>/**** OR, Build Txn and then sign using signer *****/</strong><br>Transaction transaction = <br>      TxBuilderContext.<em>init</em>(utxoSupplier, protocolParamsSupplier)<br>           .build(txBuilder);<br><br>Transaction signedTxn = signer.sign(transaction);</pre><h3><strong>Submit a transaction to Cardano network</strong></h3><p>Once a transaction is signed, you can submit it to the network using <em>TransactionService</em>.</p><pre>Result&lt;String&gt; result =           transactionService.submitTransaction(signedTxn.serialize());</pre><h3><strong>Add your own TxBuilder implementation</strong></h3><p>In some scenarios, you need to provide your own <em>TxBuilder</em> and other functions to transform the transaction object.</p><p><strong>Example :</strong><br>Right now, there is no <em>TxBuilder</em> function to set <strong><em>ttl</em></strong> parameter in the transaction object. But you can easily provide your own implementation to set ttl or add/update other parameters.</p><pre>TxBuilder txBuilder = txOuputBuilder1<br>             .and(txOuputBuilder2)<br>             .buildInputs(txInputBuilder)<br>             .andThen(otherTxBuilder)<br>             <strong>.andThen((context, transaction) -&gt; {<br>                   transaction.getBody().setTtl(100000);</strong></pre><pre><strong>                   //set or update other transaction parameters<br>             })</strong><br>             .andThen(feeCalculator(changeAddress, noOfSigners))</pre><p>So in <strong>summary</strong>, to use the composable function API, follow these below steps to build a transaction</p><ol><li>Define expected outputs</li><li>Create one or more <em>TxOutputBuilder</em> from outputs</li><li>Create a <em>TxInputBuilder</em> which selects inputs for a sender</li><li>Step-1 to Step-3 can be repeated for multiple senders</li><li>Create additional <em>TxBuilder(s)</em> to add / update different attributes in the transaction.</li><li>Create <em>TxSigner</em></li><li>Invoke <em>TxBuilderContext.init()</em> to initialize the context and then invoke <em>buildAndSign()</em> to build and sign the transaction.</li></ol><blockquote><em>In the next few posts of this series, I will go through specific examples from regular transfer to token minting to Plutus contract calls using composable function APIs.</em></blockquote><p><strong>Meanwhile</strong>, you can find different examples using composable functions in this <a href="https://github.com/bloxbean/cardano-client-examples/tree/main/src/test/java/com/bloxbean/cardano/client/example/function">GitHub repo</a></p><h3>Resources</h3><ol><li><a href="https://github.com/bloxbean/cardano-client-lib">Cardano Client Lib Project GitHub</a></li><li><a href="https://github.com/bloxbean/cardano-client-examples">Cardano Client Example GitHub</a></li></ol><blockquote><em>Join Coinmonks</em><a href="https://t.me/coincodecap"><em> Telegram Channel</em></a><em> and</em><a href="https://www.youtube.com/c/coinmonks/videos"><em> Youtube Channel</em></a><em> learn about crypto trading and investing</em></blockquote><h3>Also, Read</h3><ul><li><a href="https://coincodecap.com/bookmap-review-2021-best-trading-software">Bookmap Review</a> |<a href="https://coincodecap.com/crypto-exchange-usa"> 5 Best Crypto Exchanges in the USA</a></li><li>The Best Crypto<a href="https://medium.com/coinmonks/hardware-wallets-dfa1211730c6"> Hardware wallet</a> |<a href="https://medium.com/coinmonks/bitbns-review-38256a07e161"> Bitbns Review</a></li><li><a href="https://coincodecap.com/crypto-exchange-in-singapore">10 Best Crypto Exchange in Singapore</a> |<a href="https://coincodecap.com/buy-axs-token"> Buy AXS</a></li><li><a href="https://coincodecap.com/red-dog-casino-review">Red Dog Casino Review</a> |<a href="https://coincodecap.com/swyftx-review"> Swyftx Review</a> |<a href="https://coincodecap.com/coingate-review"> CoinGate Review</a></li><li><a href="https://coincodecap.com/best-crypto-to-invest-in-india-in-2021">Best Crypto to Invest in India</a> |<a href="https://coincodecap.com/wazirx-p2p"> WazirX P2P</a> |<a href="https://coincodecap.com/hi-dollar-review"> Hi Dollar Review</a></li><li><a href="https://coincodecap.com/5-best-crypto-trading-bots-in-canada">Best Crypto Trading bots in Canada</a> |<a href="https://coincodecap.com/kucoin-review"> KuCoin Review</a></li><li><a href="https://coincodecap.com/huobi-crypto-trading-signals">Crypto Trading Signals for Huobi</a> |<a href="https://medium.com/coinmonks/hitbtc-review-c5143c5d53c2"> HitBTC Review</a></li><li><a href="https://coincodecap.com/ftx-futures-trading">How to trade Futures on FTX Exchange</a> |<a href="https://coincodecap.com/okex-vs-binance"> OKEx vs Binance</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=be3a8b4da835" width="1" height="1" alt=""><hr><p><a href="https://medium.com/coinmonks/cardano-client-lib-new-composable-functions-to-build-transaction-in-java-part-i-be3a8b4da835">Cardano-client-lib: New composable functions to build transaction in Java— Part I</a> was originally published in <a href="https://medium.com/coinmonks">Coinmonks</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cardano-client-lib: Minting a new Native Token in Java — Part III]]></title>
            <link>https://satran004.medium.com/cardano-client-lib-minting-a-new-native-token-in-java-part-iii-1a94a21cfeeb?source=rss-3bb19096c001------2</link>
            <guid isPermaLink="false">https://medium.com/p/1a94a21cfeeb</guid>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[ada]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[cardano]]></category>
            <category><![CDATA[native-tokens]]></category>
            <dc:creator><![CDATA[Satya]]></dc:creator>
            <pubDate>Fri, 28 May 2021 16:27:14 GMT</pubDate>
            <atom:updated>2021-05-28T16:27:14.999Z</atom:updated>
            <content:encoded><![CDATA[<h3>Cardano-client-lib: Minting a new Native Token in Java — Part III</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*m8PJvu7XS-GYEhSbxUs8pw.png" /></figure><p>This is the third part of <a href="https://github.com/bloxbean/cardano-client-lib"><strong>cardano-client-lib</strong></a> series. In this post, I will explain how to create a new Native Token using Java. In this post also, we will be using <a href="https://blockfrost.io"><strong>Blockfrost</strong></a> backend api.</p><p>You can check Part I and Part II of this series before continuing with this post</p><ol><li><a href="https://medium.com/p/83fba0fee537">Cardano-client-lib: A Java Library to interact with Cardano -Part I</a></li><li><a href="https://medium.com/p/fa34f403b90e">Cardano-client-lib: Transaction with Metadata in Java- Part II</a></li></ol><p>In <strong>Cardano</strong>, you can mint a new native token without writing a smart contract. Users can transact with ada, and an unlimited number of user-defined (custom) <strong>tokens</strong> natively.</p><p>Let’s create a new native token.</p><ol><li><strong>Project and account setup</strong></li></ol><p>If you have not setup your project yet, please follow the <strong>step-1</strong> to <strong>step-6</strong> from <a href="https://medium.com/p/83fba0fee537"><strong>Part I</strong></a>.</p><p><strong>2. Create a Policy Script &amp; Policy Id</strong></p><p>In <strong>Cardano</strong>, token minting policies are written using multi-signature scripts. This allows the asset controller to express conditions such as the need for specific token issuers to agree to mint new tokens, or to forbid minting tokens after a certain slot.</p><p>The library provides following classes to create different types of supported policies :</p><ul><li>ScriptPubKey</li><li>ScriptAll</li><li>ScriptAny</li><li>ScriptAtLeast</li><li>RequireTimeAfter</li><li>RequireTimeBefore</li></ul><p>You can build a very simple minting policy, which grants the right to mint tokens to a single key or build a complex policy by combining above classes.</p><p>In this post, we will create a simple policy, which grants the right to mint tokens to a single key.</p><p>Let’s create a key-pair which we can be used to create the policy.</p><pre>Keys keys = KeyGenUtil.<em>generateKey</em>();<br>VerificationKey vkey = keys.getVkey();<br>SecretKey skey = keys.getSkey();</pre><p>Create a <strong>ScriptPubKey</strong>, which grants the right to mint tokens to the above generated key.</p><pre>ScriptPubkey scriptPubkey = ScriptPubkey.<em>create</em>(vkey);</pre><p>We can now generate <strong>policy id</strong> from <strong>scriptPubKey</strong> object.</p><pre>String policyId = scriptPubkey.getPolicyId();</pre><p><strong>3. Define our new native token using MultiAsset class</strong></p><p>Create an instance of MultiAsset class. Use the policy id generated in previous step. Create an asset object with a custom name and token quantity.</p><pre>MultiAsset multiAsset = new MultiAsset();<br>multiAsset.setPolicyId(policyId);<br>Asset asset = new Asset(&quot;TestCoin&quot;, BigInteger.<em>valueOf</em>(250000));<br>multiAsset.getAssets().add(asset);</pre><p><strong>4. Attach Metadata to Mint Token transaction (Optional)</strong></p><p>If you want to attach some metadata to this token mint transaction, you can do so using Metadata apis provided by the library.</p><pre>CBORMetadataMap tokenInfoMap<br>        = new CBORMetadataMap()<br>        .put(&quot;token&quot;, &quot;Test Token&quot;)<br>        .put(&quot;symbol&quot;, &quot;TTOK&quot;);<br><br>CBORMetadataList tagList<br>        = new CBORMetadataList()<br>        .add(&quot;tag1&quot;)<br>        .add(&quot;tag2&quot;);<br><br>Metadata metadata = new CBORMetadata()<br>        .put(new BigInteger(&quot;770001&quot;), tokenInfoMap)<br>        .put(new BigInteger(&quot;770002&quot;), tagList);</pre><p><strong>5. Create Token Minting request</strong></p><p>Create a token minting transaction request using MintTransaction class.</p><pre>MintTransaction mintTransaction =<br>        MintTransaction.<em>builder</em>()<br>                .sender(sender)<br>                .mintAssets(Arrays.<em>asList</em>(multiAsset))<br>                .policyScript(scriptPubkey)<br>                .policyKeys(Arrays.<em>asList</em>(skey))<br>                .build();</pre><blockquote><strong>Note:</strong> Apart from setting the<strong> multiAsset</strong> object created in the <strong>step-3</strong>, we are also adding our <strong>policy script</strong> (<strong>scriptPubKey</strong>) and <strong>policy secret key</strong> (<strong>skey</strong>) which were generated in step-2.</blockquote><blockquote>If you don’t set policy script and policy keys, the token mint transaction will fail.</blockquote><p>If the receiver field is not set, the minted token will be allocated to the sender account.</p><p><strong>6. Calculate TTL (Time To Live) and fee</strong></p><p><em>Calculate TTL</em></p><pre>long ttl = blockService.getLastestBlock().getValue().getSlot() + 1000;</pre><pre>TransactionDetailsParams detailsParams =<br>        TransactionDetailsParams.<em>builder</em>()<br>                .ttl(ttl)<br>                .build();</pre><p><em>Calculate fee and set the fee in mint transaction</em></p><pre>BigInteger fee<br>         = feeCalculationService.calculateFee(mintTransaction,            detailsParams, metadata);</pre><pre><br>mintTransaction.setFee(fee);</pre><p><strong>7. Submit the Mint Token transaction</strong></p><p>Finally, submit the token mint transaction using <strong>TransactionHelperService</strong>.</p><pre>Result&lt;String&gt; result <br>         = transactionHelperService.mintToken(mintTransaction,     detailsParams, metadata);</pre><pre>if(result.isSuccessful())<br>    System.<em>out</em>.println(&quot;Transaction Id: &quot; + result.getValue());<br>else<br>    System.<em>out</em>.println(&quot;Transaction failed: &quot; + result);</pre><p><strong>8. Check transaction details in Cardano Explorer</strong></p><p>Now go to <a href="https://explorer.cardano-testnet.iohkdev.io"><strong>Cardano Testnet Explorer</strong></a> and check transaction details.</p><p>It may take some time for the transaction to be mined.</p><p>You should now see the minted token under the receiver’s address. (If no receiver is specified, under sender’s address)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/858/1*7JzlQd31GRjo4fscXHlnrg.png" /></figure><p><strong>9. Get details of our newly minted asset</strong></p><p>First get <strong>asset id</strong> by combining previously generated policy id and then the HEX encoded value of our <strong>asset name</strong>.</p><pre>String policyId = &quot;abe83f0124320fc4e6f50605e7986390453bcc0c913c920a249545eb&quot;;<br>String assetName = HexUtil.<em>encodeHexString</em>(&quot;TestCoin&quot;.getBytes(StandardCharsets.<em>UTF_8</em>));<br><br>String assetId = policyId + assetName;</pre><p>Then use AssetService to get asset details.</p><pre>Result&lt;Asset&gt; asset = assetService.getAsset(assetId);<br>System.<em>out</em>.println(JsonUtil.<em>getPrettyJson</em>(asset.getValue()));</pre><p>Output:</p><pre>{<br>  &quot;policy_id&quot; : &quot;abe83f0124320fc4e6f50605e7986390453bcc0c913c920a249545eb&quot;,<br>  &quot;asset_name&quot; : &quot;54657374436f696e&quot;,<br>  &quot;fingerprint&quot; : &quot;asset1uw2v9tzrp6ntvzc48l28j2jc2r4k569hxxk463&quot;,<br>  &quot;quantity&quot; : &quot;4000&quot;,<br>  &quot;initial_mint_tx_hash&quot; : &quot;d9da361f3e5237832cfcbdea16d440c9ea3e5026c7370c368291aafb5c2646a6&quot;<br>}</pre><p><strong>10. Create complex policies by combining different script classes</strong></p><p>In the below policy script example, we are creating a <strong>ScriptAll</strong> policy by combining <strong>RequireTimeBefore</strong> and <strong>ScriptAtLeast</strong> script.</p><pre>//Key 1 - Single Key Policy<br>Tuple&lt;ScriptPubkey, Keys&gt; tuple1 = ScriptPubkey.<em>createWithNewKey</em>();<br>ScriptPubkey scriptPubkey1 = tuple1._1;<br>SecretKey sk1 = tuple1._2.getSkey();</pre><pre>//Key 2 - Single Key Policy<br>Tuple&lt;ScriptPubkey, Keys&gt; tuple2 = ScriptPubkey.<em>createWithNewKey</em>();<br>ScriptPubkey scriptPubkey2 = tuple2._1;<br>SecretKey sk2 = tuple2._2.getSkey();</pre><pre>//Key 3 - Single Key Policy<br>Tuple&lt;ScriptPubkey, Keys&gt; tuple3 = ScriptPubkey.<em>createWithNewKey</em>();<br>ScriptPubkey scriptPubkey3 = tuple3._1;<br>SecretKey sk3 = tuple3._2.getSkey();</pre><pre>//AtLeast policy with min-required key 2<br>ScriptAtLeast scriptAtLeast = new ScriptAtLeast(2)<br>        .addScript(scriptPubkey1)<br>        .addScript(scriptPubkey2)<br>        .addScript(scriptPubkey3);<br><br>long slot = getTtl();<br>RequireTimeBefore requireTimeBefore = new RequireTimeBefore(slot);</pre><pre>//Create the final ScriptAll policy by combining RequireTimeBefore and ScriptAtLeast<br>ScriptAll scriptAll = new ScriptAll()<br>        .addScript(requireTimeBefore)<br>        .addScript(<br>                scriptAtLeast<br>        );</pre><p>You can print the the JSON value of Script object and store it in a file. The generated JSON object is compatible with cardano-cli command line tool.</p><p><strong><em>Full source code:</em></strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d97025afaff6f27a9fe2eda46a61f1cb/href">https://medium.com/media/d97025afaff6f27a9fe2eda46a61f1cb/href</a></iframe><p><strong><em>Resources</em></strong></p><ol><li>Cardano-client-lib GitHub repository (<a href="https://github.com/bloxbean/cardano-client-lib">https://github.com/bloxbean/cardano-client-lib</a>)</li><li>Example Source code (<a href="https://github.com/bloxbean/cardano-client-examples">https://github.com/bloxbean/cardano-client-examples</a>)</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1a94a21cfeeb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cardano-client-lib: Transaction with Metadata in Java — Part II]]></title>
            <link>https://satran004.medium.com/cardano-client-lib-transaction-with-metadata-in-java-part-ii-fa34f403b90e?source=rss-3bb19096c001------2</link>
            <guid isPermaLink="false">https://medium.com/p/fa34f403b90e</guid>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[cardano]]></category>
            <category><![CDATA[metadata]]></category>
            <category><![CDATA[ada]]></category>
            <dc:creator><![CDATA[Satya]]></dc:creator>
            <pubDate>Fri, 28 May 2021 16:26:14 GMT</pubDate>
            <atom:updated>2021-05-28T16:26:37.066Z</atom:updated>
            <content:encoded><![CDATA[<h3>Cardano-client-lib: Transaction with Metadata in Java — Part II</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*nRHZ6zdgxU9-1cvRvA7wng.png" /></figure><p>In this post, we will see how you can create and post a transaction with <strong>metadata</strong> to <a href="https://cardano.org/"><strong>Cardano</strong></a> network in a Java application using <a href="https://github.com/bloxbean/cardano-client-lib"><strong>cardano-client-lib</strong></a>.</p><p><a href="https://github.com/bloxbean/cardano-client-lib"><strong>Cardano-client-lib</strong></a> is a Java library which provides support to create, sign and submit transaction to the Cardano network. Check <a href="https://medium.com/p/83fba0fee537"><strong>Part-I</strong></a> of this series to know more about Cardano-client-lib and the other functionalities provided by this library.</p><p>In this post we will be using <a href="https://blockfrost.io/"><strong>Blockfrost</strong></a> backend Api.</p><p>Cardano Metadata as defined in this <a href="https://iohk.io/en/blog/posts/2020/11/03/getting-to-grips-with-metadata-on-cardano/">blog</a> :-</p><blockquote>Metadata tells the story of a transaction and there are many ways to interact with this story. Developers can take advantage of metadata by embedding details directly into a transaction, and ada users can search for specific information in the Cardano Explorer. The data can be added directly, or, for larger amounts, it is possible to create a Merkle tree of the data and put the root hash of the Merkle tree on the blockchain. Once this is done, it can be proved that the data existed at a specific point of time and that it remains permanently on the chain for future reference.</blockquote><p><strong>Cardano-client-lib</strong> provides simple apis to create metadata. It also provides helpers to convert metadata to JSON and vice versa.</p><p>Let’s create a payment transaction and add some metadata to it.</p><ol><li><strong>Project and account setup</strong></li></ol><p>If you have not setup your project yet, please follow the <strong>step-1</strong> to <strong>step-6</strong> from <a href="https://medium.com/p/83fba0fee537"><strong>Part I</strong></a>.</p><p><strong>2. Create a metadata object</strong></p><p>To create a metadata object, you have to start with CBORMetadata class. You can also use CBORMetadataMap and CBORMetadataList if you want to set the value as Map or List.</p><pre>CBORMetadataMap productDetailsMap<br>        = new CBORMetadataMap()<br>        .put(&quot;code&quot;, &quot;PROD-800&quot;)<br>        .put(&quot;slno&quot;, &quot;SL20000039484&quot;);<br><br>CBORMetadataList tagList<br>        = new CBORMetadataList()<br>        .add(&quot;laptop&quot;)<br>        .add(&quot;computer&quot;);<br><br>Metadata metadata = new CBORMetadata()<br>        .put(new BigInteger(&quot;670001&quot;), productDetailsMap)<br>        .put(new BigInteger(&quot;670002&quot;), tagList);</pre><p>In the above example, we are first creating a Map which contains code and serial no. We are then creating a List to hold multiple tags.</p><p>Finally, we are creating a Metadata object and setting <strong>productDetailsMap</strong> and <strong>tagList</strong> with metadata labels 670001, 670002 respectively.</p><p>You can create a multi-level nested structure, but the top-level object should be Metadata.</p><p><strong>3. Create a transaction request object</strong></p><p>As explained in the <a href="https://medium.com/p/83fba0fee537">Part I</a>, let’s create a transaction with PaymentTransaction class.</p><pre>PaymentTransaction paymentTransaction =<br>          PaymentTransaction.<em>builder</em>()<br>                .sender(sender)<br>                .receiver(receiver)<br>                .amount(BigInteger.<em>valueOf</em>(20000000))<br>                .unit(<em>LOVELACE</em>)<br>                .build();</pre><p><strong>4. Calculate TTL (Time-to-Live)</strong></p><p>Use BlockService to get the latest slot number and then calculate ttl.</p><pre>long ttl = blockService.getLastestBlock().getValue().getSlot() + 1000;<br>TransactionDetailsParams detailsParams =<br>        TransactionDetailsParams.<em>builder</em>()<br>                .ttl(ttl)<br>                .build();</pre><p><strong>5. Calculate Fee</strong></p><p>Use <strong>FeeCalculatorService</strong> to calculate fee. Make sure to send all three parameters “<strong>PaymentTransaction</strong>, <strong>TransactionDetailsParams</strong> and <strong>Metadata</strong>” to FeeCalculatorService.</p><p>Set the calculated fee in PaymentTransaction request.</p><pre>BigInteger fee <br>         = feeCalculationService.calculateFee(paymentTransaction,                   detailsParams, <strong>metadata</strong>);<br><br>paymentTransaction.setFee(fee);</pre><p><strong>6. Submit Transaction with Metadata</strong></p><p>Now submit the transaction request to the network using TransactionHelperService.</p><p><strong>Note: </strong>Make sure to pass “metadata” parameter in the transfer call.</p><pre>Result&lt;String&gt; result<br>          = transactionHelperService.transfer(paymentTransaction,    detailsParams, <strong>metadata</strong>);<br></pre><pre>if(result.isSuccessful())<br>    System.<em>out</em>.println(&quot;Transaction Id: &quot; + result.getValue());<br>else<br>    System.<em>out</em>.println(&quot;Transaction failed: &quot; + result);</pre><p><strong>7. Check transaction details in Cardano Explorer</strong></p><p>Now go to <a href="https://explorer.cardano-testnet.iohkdev.io">Cardano Testnet Explorer</a> and check the transaction details.</p><p>It may take some time for the transaction to be mined.</p><p>Now you can see the metadata in Cardano explorer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/697/1*KOsqkPj9QS9qiuzp1bBPww.png" /></figure><blockquote>Metadata can be added to a Native token transfer in similar ways.</blockquote><p><strong>Metadata Helper Class</strong></p><p>There are few helper classes which can be used to convert a JSON (No Schema) object to metadata format and vice-versa.</p><p>But the Json payload has to follow the format mentioned in this <a href="https://github.com/input-output-hk/cardano-node/blob/master/doc/reference/tx-metadata.md#no-schema">wiki</a>.</p><pre>JsonNoSchemaToMetadataConverter<br>MetadataToJsonNoSchemaConverter</pre><p><strong><em>Check also:</em></strong></p><ul><li>Part I : <a href="https://medium.com/p/83fba0fee537">Cardano-client-lib: A Java Library to interact with Cardano — Part I</a></li><li>Part III : <a href="https://medium.com/p/1a94a21cfeeb">Cardano-client-lib: Minting a new Native Token in Java — Part III</a></li></ul><h3><strong><em>Resources</em></strong></h3><ul><li><strong>Cardano-client-lib GitHub repository</strong> (<a href="https://github.com/bloxbean/cardano-client-lib">https://github.com/bloxbean/cardano-client-lib</a>)</li><li><strong>Example Source code</strong> (<a href="https://github.com/bloxbean/cardano-client-examples">https://github.com/bloxbean/cardano-client-examples</a>)</li></ul><p><strong><em>Full Source code</em></strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8c3064f734fcf4868aa672e21bbaf6ce/href">https://medium.com/media/8c3064f734fcf4868aa672e21bbaf6ce/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fa34f403b90e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cardano-client-lib : A Java Library to interact with Cardano — Part I]]></title>
            <link>https://satran004.medium.com/cardano-client-lib-a-java-library-to-interact-with-cardano-part-i-83fba0fee537?source=rss-3bb19096c001------2</link>
            <guid isPermaLink="false">https://medium.com/p/83fba0fee537</guid>
            <category><![CDATA[native-tokens]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[cardano]]></category>
            <category><![CDATA[ada]]></category>
            <dc:creator><![CDATA[Satya]]></dc:creator>
            <pubDate>Fri, 28 May 2021 16:22:13 GMT</pubDate>
            <atom:updated>2022-12-03T08:06:10.956Z</atom:updated>
            <content:encoded><![CDATA[<h3>Cardano-client-lib : A Java Library to interact with Cardano — Part I</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*IC6oKteSAqC50K9ueCfmJg.png" /></figure><p><strong>Update: </strong><em>For latest “Getting Started Guide”, you can check this tutorial </em><a href="https://cardano-client.bloxbean.com/docs/gettingstarted/simple-transfer"><em>https://cardano-client.bloxbean.com/docs/gettingstarted/simple-transfer</em></a><em><br>The high level api used to build transaction in this post (from section #7) is no longer recommended. For flexibility, you should build the transactions using “Composable Functions api” mentioned in the above getting started guide.</em></p><p>In this post, I am going to introduce a Java library called “<a href="https://github.com/bloxbean/cardano-client-lib"><strong>cardano-client-lib</strong></a>”. You can use this library in a Java application to interact with Cardano blockchain.</p><h3><strong>Why a Cardano Client Java Library ?</strong></h3><p>Currently, I am working on a project called “<a href="https://github.com/bloxbean/intelliada"><strong>Cardano IntelliJ IDEA plugin (IntelliAda)</strong></a>”, which is a <strong>Catalyst Fund 3</strong> funded project. You can check the Catalyst proposal <a href="https://cardano.ideascale.com/a/dtd/Cardano-IntelliJ-IDEA-Plugin-MVP/333570-48088">here</a>. When I started this project, I realized that there are client side libraries available for Cardano in languages like JavaScript, Rust (<a href="https://github.com/Emurgo/cardano-serialization-lib.git"><strong>Cardano-serilization-lib</strong></a>), but I was not able find any Java library doing the similar thing without relying on <strong>cardano-cli</strong> (Cardano command line tool).</p><p>As Cardano IntelliJ Plugin is written in java, I need a client library in Java, so that I don’t need to rely on Cardano-cli tool inside the plugin to generate address, sign transaction and other operations. Because of that I started working on <strong>cardano-client-lib</strong> project to provide address generation, transaction serialization and signing support through a Java library.</p><p>The preview version <strong>(0.1.0)</strong> of this library in now available in Maven central repository, so you can use it in your java application.</p><p>This library also provides support to interact with Cardano blockchain to query blockchain and submit transactions through few simple Backend Apis. Currently, only one implementation available for Backend Api, which is for <a href="https://blockfrost.io/"><strong>Blockfrost</strong></a> endpoint. More backends will be supported in future releases. (<a href="https://github.com/input-output-hk/cardano-wallet">Cardano Wallet Backend</a>, <a href="https://github.com/KtorZ/cardano-ogmios">Cardano-ogmios</a> ..)</p><p>The following key features are currently supported in this library</p><ul><li>Address Generation (Base Address, Enterprise Address)</li><li>Build and serialize transaction to CBOR format</li><li>Apis to build Metadata</li><li>A converter to convert Metadata to Json (No Schema)</li><li>Payment transaction (ADA, Native tokens) signing and submission to Cardano network (through Blockfrost Backend Api)</li><li>Transaction with metadata</li><li>Api to mint native tokens</li><li>Apis to query Cardano blockchain through many Blockfrost backend apis (AddressService, AssetService, BlockService, EpochService,MetadataService, TransactionService …)</li></ul><p><strong>Current Limitations</strong></p><ul><li>Currently, this library is using “<a href="https://github.com/Emurgo/cardano-serialization-lib"><strong>Cardano-serialization-lib</strong></a>” rust library through <strong>JNI</strong>, mainly for address generation and transaction signing. So it bundles the platform dependent binaries of <a href="https://github.com/Emurgo/cardano-serialization-lib">Cardano-serialization-lib</a> in the Jar. Because of that, this library is currently supported only on the following platforms</li></ul><p>- <strong>Apple MacOS (Intel and Apple Silicon)</strong><br>- <strong>Linux (x86_64) (Ubuntu 18.04 and above or compatible …)</strong><br>-<strong>Windows 64bits (x86_64)</strong></p><blockquote><strong>Note:</strong> This limitation is temporary. The plan is to remove this dependency in the future release by implementing address generation and transaction signing natively in Java.</blockquote><ul><li>The library doesn’t support any stake pool related operations. Though in future, stake pool related operations can be added.</li></ul><p>Let’s see how we can use this library to create and post a transfer transaction with Ada.</p><ol><li><strong>Add cardano-client-lib dependency to your application</strong></li></ol><p>If you are using Maven,</p><pre>&lt;dependency&gt;<br>    &lt;groupId&gt;com.bloxbean.cardano&lt;/groupId&gt;<br>    &lt;artifactId&gt;cardano-client-lib&lt;/artifactId&gt;<br>    &lt;version&gt;0.1.0&lt;/version&gt;<br>&lt;/dependency&gt;</pre><p>If you are using Gradle,</p><pre>implementation &#39;com.bloxbean.cardano:cardano-client-lib:0.1.0&#39;</pre><p><strong>Note:</strong> You can check the latest released version in project’s <a href="https://github.com/bloxbean/cardano-client-lib">GitHub</a>.</p><p><strong>2. Create a new Account</strong></p><pre>Account account = new Account(Networks.<em>testnet</em>());<br>String baseAddress = account.baseAddress();</pre><p><strong>3. Import from Mnemonic Phrase</strong></p><p>Provide 24 words mnemonic phrase to derive the base account address.</p><pre>String mnemonic = &quot;behind hope swing table fat joy phone spoil response exercise dose fame mystery day food lens debate slam lawsuit board behind allow excuse extend&quot;;</pre><pre>Account account = new Account(Networks.<em>testnet</em>(), mnemonic);<br>String baseAddress = account.baseAddress();</pre><p>4. <strong>Get Backend Service</strong></p><p>Provide Blockfrost Cardano network and Project Id to get an instance of Blockfrost backend service.</p><p><strong>Register at </strong><a href="https://blockfrost.io/"><strong>https://blockfrost.io/</strong></a><strong> to get a free account and a project id for Cardano Testnet.</strong></p><pre>BackendService backendService =<br>     BackendFactory.<em>getBlockfrostBackendService</em>(<br>        Constants.<em>BLOCKFROST_TESTNET_URL</em>, &lt;project_id&gt;);</pre><p><strong>5. Get Other services from Backend Service</strong></p><p>The followings are the example of few major services you can get from BackendService. You can use these services to interact with Cardano blockchain.</p><p><strong>a.</strong> Get an instance of <strong>TransactionHelperService</strong> to build a payment or token mint transaction and submit to the Cardano network.</p><pre>TransactionHelperService txnHelperService <br>               = backendService.getTransactionHelperService();</pre><p><strong>b.</strong> Get an instance of <strong>FeeCalculationService</strong> to calculate the estimated fees of a transaction.</p><pre>FeeCalculationService feeCalcService <br>                        = backendService.getFeeCalculationService();</pre><p><strong>c. </strong>Get <strong>TransactionService</strong> to query the blockchain for a transaction id.</p><pre>TransactionService txnService<br>                        = backendService.getTransactionService();</pre><p><strong>d.</strong> Get <strong>BlockService</strong> to get the block information from the blockchain.</p><pre>BlockService blockService = backendService.getBlockService();</pre><p><strong>e.</strong> Get an instance of <strong>AssetService</strong> to get Asset details.</p><pre>AssetService assetService = backendService.getAssetService();</pre><p><strong>f.</strong> Get an instance of <strong>UtxoService </strong>to fetch Utxos.</p><pre>UtxoService utxoService = backendService.getUtxoService()</pre><p><strong>g.</strong> Get an instance of <strong>MetadataService</strong> to fetch metdata</p><pre>MetadataService metadataService <br>                        = backendService.getMetadataService();</pre><p><strong>6. Top-up your account with test Ada</strong></p><p>If you are on Cardano testnet, you can get some Testnet Ada token from the Testnet faucet <a href="https://developers.cardano.org/en/testnets/cardano/tools/faucet/">here</a>.</p><p><strong><em>Note:</em></strong><em> You can use Account api to create new testnet accounts.</em></p><p><strong>7. Create your first Ada Payment Transaction</strong></p><p>Now that we have some test Ada tokens, we can create a payment transaction to transfer Ada from funded account to another account.</p><pre>PaymentTransaction paymentTransaction =<br>        PaymentTransaction.<em>builder</em>()<br>             .sender(senderAccount) //Sender Account object<br>             .receiver(receiver)   // Receiver baseAddress as String<br>             .amount(BigInteger.<em>valueOf</em>(1500000))<br>             .unit(CardanoConstants.LOVELACE)<br>             .build();</pre><p><strong>Note:</strong> In the above transaction, we are trying to send 1.5 Ada (1500000 Lovelace) from sender’s account to receiver’s account.</p><p><strong>8. Get the latest slot information and then calculate TTL (Time To Live)</strong></p><p>In the below code snippet, we are getting the latest block through BlockService and then adding 1000 to the current slot number to calculate TTL.</p><pre>long ttl = blockService.getLastestBlock().getValue().getSlot() + 1000;</pre><p><strong>9. Create a TransactionDetailsParams Object, set TTL and calculate the estimated fee using FeeCalculation service</strong></p><pre>TransactionDetailsParams detailsParams =<br>        TransactionDetailsParams.<em>builder</em>()<br>                .ttl(ttl)<br>                .build();<br><br>BigInteger fee <br>     = feeCalculationService.calculateFee(paymentTransaction, detailsParams, null); </pre><p><strong>10. Set the fee in the transaction request object</strong></p><p>Now that we have estimated fee for our transaction, let’s set it in our PaymentTransaction request object.</p><pre>paymentTransaction.setFee(fee);</pre><p><strong>11. Submit Transaction to the Cardano network</strong></p><p>To submit the transaction to the network, you need to use <strong>TransactionHelperService</strong>. TransactionHelperService will get the required Utxos and then create the inputs and outputs accordingly before sending the transaction request to the network. It also calculates the min-ada required for each outputs.</p><pre>Result&lt;String&gt; result <br>          = transactionHelperService.transfer(paymentTransaction, detailsParams);</pre><p>If everything is ok, you should get the result success status as “true” and result value as “Transaction id”.</p><pre>if(result.isSuccessful())<br>    System.<em>out</em>.println(&quot;Transaction Id: &quot; + result.getValue());<br>else<br>    System.<em>out</em>.println(&quot;Transaction failed: &quot; + result);</pre><p>Now wait for sometime, so that the our transaction is mined.</p><p>You can now go to <a href="https://explorer.cardano-testnet.iohkdev.io/en">Cardano Testnet Explorer</a> to check the transaction details.</p><p><strong>12. Transfer Native Token</strong></p><p>To transfer native tokens from one account to another, you need to use the same PaymentTransaction api to build the native token transfer request and set the native token’s <strong>asset id</strong> in the “unit” field of the payment request. Other steps are exactly same.</p><pre>PaymentTransaction paymentTransaction =<br>        PaymentTransaction.<em>builder</em>()<br>                .sender(senderAccount)<br>                .receiver(receiver)<br>                .amount(BigInteger.<em>valueOf</em>(3000))<br>                .unit(&quot;d11b0562dcac7042636c9dbb44897b38.......&quot;)<br>                .build();</pre><pre>//Calculate Ttl = Latest slot + 1000<br>long ttl = blockService<br>              .getLastestBlock().getValue().getSlot() + 1000;<br>TransactionDetailsParams detailsParams =<br>        TransactionDetailsParams.<em>builder</em>()<br>                .ttl(ttl)<br>                .build();</pre><pre>//Calculate fee<br>BigInteger fee <br>      = feeCalculationService.calculateFee(paymentTransaction,            detailsParams, null);</pre><pre>//Set fee<br>paymentTransaction.setFee(fee);<br><br>Result&lt;String&gt; result <br>            = transactionHelperService.transfer(paymentTransaction, detailsParams);</pre><p><strong><em>Check also :</em></strong></p><ul><li>Part II : <a href="https://medium.com/p/fa34f403b90e">Cardano-client-lib: Transaction with Metadata in Java — Part II</a></li><li>Part III : <a href="https://medium.com/p/1a94a21cfeeb">Cardano-client-lib: Minting a new Native Token in Java — Part III</a></li></ul><h3><strong><em>Resources</em></strong></h3><ul><li><strong>Cardano-client-lib GitHub repository</strong> (<a href="https://github.com/bloxbean/cardano-client-lib">https://github.com/bloxbean/cardano-client-lib</a>)</li><li><strong>Example Source code</strong> (<a href="https://github.com/bloxbean/cardano-client-examples">https://github.com/bloxbean/cardano-client-examples</a>)</li></ul><p><strong><em>Full Source Code:</em></strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/daa9be1ba0c878a81d2570a1b6641c21/href">https://medium.com/media/daa9be1ba0c878a81d2570a1b6641c21/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=83fba0fee537" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kafka Web3 Source Connector — Publish Web3 compatible Blockchain data to Kafka topics]]></title>
            <link>https://satran004.medium.com/kafka-web3-source-connector-publish-web3-compatible-blockchain-data-to-kafka-topics-1310c83decd0?source=rss-3bb19096c001------2</link>
            <guid isPermaLink="false">https://medium.com/p/1310c83decd0</guid>
            <category><![CDATA[web3]]></category>
            <category><![CDATA[kafka]]></category>
            <category><![CDATA[kafka-connector]]></category>
            <category><![CDATA[ethereum]]></category>
            <category><![CDATA[aion]]></category>
            <dc:creator><![CDATA[Satya]]></dc:creator>
            <pubDate>Thu, 16 Jul 2020 05:48:33 GMT</pubDate>
            <atom:updated>2020-07-16T05:48:33.387Z</atom:updated>
            <content:encoded><![CDATA[<h3>Kafka Web3 Source Connector — Publish Web3 compatible Blockchain data to Kafka topics</h3><p>In this post, I am going to explain how to retrieve Blocks / Transactions / Events data from any Web3 compatible blockchain (Ethereum, Aion, …) and publish to Kafka topics in real-time.</p><h3>Kafka Connectors ?</h3><p>Kafka Connectors are ready to use components, which can be used to import data from external systems to Kafka topics and export data from Kafka topics to external systems. Kafka Connectors are written using Kafka Connect framework, which is a set of Java Api provided by Kafka to write a connector.</p><p>There are two types of Kafka connectors :</p><ul><li><strong>Source Connector</strong> : To collect data from an external system and publish into a Kafka topic</li><li><strong>Sink Connector</strong> : To deliver data from a Kafka topic to an external system</li></ul><p>Most of the time, you don’t need to write your own connector. You can check at <a href="https://www.confluent.io/hub/">Confluent Hub</a> if a connector available for your external system.</p><h3>Kafka Web3 Source Connector</h3><p>I will go through a Source Connector implementation, “<strong>Kafka Web3 Source Connector</strong>”. The source for this project can be found at <a href="https://github.com/satran004/kafka-web3-connector">https://github.com/satran004/kafka-web3-connector</a> .</p><p>You may want to check the source code of this project to know how to write your own Kafka connector.</p><p>This source connector implementation can read blockchain data from a Web3 Jsonrpc endpoint and publish Blocks / Transactions / Events data to any Kafka topic.</p><p>There are two source connector implementations in this project:</p><ol><li><strong>Block Source Connector :</strong> <em>com.bloxbean.kafka.connectors.web3.source.blocks.BlockSourceConnector</em></li><li><strong>Event Logs Connector :</strong> <em>com.bloxbean.kafka.connectors.web3.source.events.EventSourceConnector</em></li></ol><p><strong><em>Block Source Connector</em></strong></p><p>You can use “Block Source Connector” to fetch blocks or transactions data from a web3 jsonrpc endpoint of a blockchain (Example: Ethereum, Aion) and publish the json data to a topic.</p><p>It supports two scenarios:</p><ul><li>Publish Blocks with Transaction data to one Kafka topic</li><li>Publish Blocks with transaction ids to one topic and transaction details to another topic.</li></ul><p><strong><em>Event Logs Connector</em></strong></p><p>This source connector can be used to retrieve smart contract event logs from a web3 compatible blockchain through it’s web3 jsonrpc endpoint and publish to Kafka topics.</p><p>It supports following scenarios</p><ul><li>Publish all event logs to a Kafka topic</li><li>Apply event log filters and publish only matching event logs to a Kafka topic</li></ul><p>You can use these connectors both in <em>standalone</em> and <em>distributed</em> mode.</p><p>For simplicity, I am providing the configuration for standalone mode in this post. For distributed mode configuration, you can refer to the <strong>“config” </strong>folder of this project.</p><h3><strong>How to Run In Standalone Mode From Source</strong></h3><p>&gt; Check out the source from <a href="https://github.com/satran004/kafka-web3-connector">https://github.com/satran004/kafka-web3-connector</a></p><p>&gt; Install Java 1.8 (Minimum) , Maven, Kafka on your machine</p><p>&gt; Start Kafka server</p><p><strong>Compile and build the package</strong></p><pre>$&gt; mvn clean package</pre><h3><strong>Run Block Source connector to fetch blocks from web3 json rpc endpoint</strong></h3><p>You can find a sample configuration for Block Connector in standalone mode under “config” folder. Here’s a sample configuration to fetch blocks from Aion blockchain. Similar configuration can be found for Ethereum blockchain under the same folder.</p><ul><li>Replace proper value for web3_rpc_url, start_block.</li><li>If you want to publish blocks and transactions in to separate topics, update <strong>topic</strong> &amp; <strong>transaction_topic</strong> properties accordingly. Otherwise, you can comment <strong>transaction_topic</strong> property.</li></ul><p>Edit “<em>config/connector-web3-blocks-source.properties</em>”</p><pre>###### connector-web3-blocks-source.properties   ######</pre><pre>name=bloxbean-web3-source-connector</pre><pre>connector.class=com.bloxbean.kafka.connectors.web3.source.blocks.BlockSourceConnector</pre><pre>tasks.max=1</pre><pre>web3_rpc_url=http://&lt;host&gt;:8545</pre><pre>topic=aion-blocks</pre><pre><em>#To publish transactions with blocks, comment the below line. #Otherwise, transactions will be published to the following topic<br></em>transaction_topic=aion-transactions</pre><pre><em>#Comma separated list of ignored fields from Block object.<br></em>ignore_block_fields=logsBloom,extraData</pre><pre><em>#Comma separated ist of ignored field from Transaction object. #Supported options: input<br></em>ignore_transaction_fields=input<br><br>start_block=4721700<br>block_time=10<br>no_of_blocks_for_finality=0</pre><p><strong>To run,</strong></p><p>&gt; Set KAFKA_HOME environment variable</p><pre>$&gt; export KAFKA_HOME=&lt;path_to_kafka_installation_folder&gt;</pre><pre>$&gt; $KAFKA_HOME/bin/connect-standalone.sh config/connect-standalone.properties config/connector-web3-blocks-source.properties</pre><p>If everything is working as expected, the connector will start fetching blocks in real-time and you should be seeing similar logs</p><pre>[2020-07-16 12:46:32,467] INFO WorkerSourceTask{id=bloxbean-web3-source-connector-0} Source task finished initialization and start (org.apache.kafka.connect.runtime.WorkerSourceTask:200)<br>[2020-07-16 12:46:32,537] INFO Cluster ID: ri4jhQhdTCuB7RuCMLjbhQ (org.apache.kafka.clients.Metadata:365)<br>[2020-07-16 12:46:32,928] INFO Successfully fetched block : 4729045  (com.bloxbean.kafka.connectors.web3.source.blocks.BlockSourceTask:94)<br>[2020-07-16 12:46:32,983] INFO Successfully fetched block : 4729046  (com.bloxbean.kafka.connectors.web3.source.blocks.BlockSourceTask:94)</pre><p>Now check the kafka topic for published messages</p><pre>$&gt; $KAFKA_HOME/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic aion-blocks --from-beginning</pre><p><strong>Note: </strong>Make sure the topic name in the above command is same as the topic name mentioned in the connector configuration file.</p><h3>Run Event Logs Source connector to fetch Event Logs from web3 json rpc endpoint</h3><p>You can find a sample configuration for Event Log Connector in standalone mode under “config” folder. Here’s a sample configuration to fetch events from Aion blockchain. Similar configuration can be found for Ethereum blockchain under the same folder.</p><p>The below configuration fetches all delegation events from Aion Staking Pool Registry contract. Check event_logs_filter_address &amp; event_logs_filter_topics properties.</p><ul><li>You can customize event_logs_filter_* values according to your requirement.</li><li>Provide value for web3_rpc_url property.</li><li>Update topic, start_block property if required.</li></ul><p>Edit “<em>config/connector-web3-blocks-source.properties</em>”</p><pre>name=bloxbean-web3-events-source-connector<br>connector.class=com.bloxbean.kafka.connectors.web3.source.events.EventSourceConnector<br>tasks.max=1</pre><pre>web3_rpc_url=http://&lt;host&gt;:8545</pre><pre>topic=web3-events</pre><pre>start_block=6117319<br>block_time=10<br>no_of_blocks_for_finality=0<br><br><em>####################################################################################<br># The following options are only applicable for EventsSourceConnector<br>####################################################################################<br></em>event_logs_filter_addresses=0xa008e42a76e2e779175c589efdb2a0e742b40d8d421df2b93a8a0b13090c7cc8</pre><pre>event_logs_filter_topics=0x41445344656c6567617465640000000000000000000000000000000000000000<br><br><em>####################################################################################<br># Target kafka topic&#39;s key<br># Comma separated list of following options<br># Options: blockNumber, logIndex, address, topic, transactionHash, transactionIndex<br># Default: transactionHash,logIndex<br>####################################################################################<br>#event_logs_kafka_keys=</em></pre><p><strong>To run,</strong></p><p>&gt; Set KAFKA_HOME environment variable</p><pre>$&gt; export KAFKA_HOME=&lt;path_to_kafka_installation_folder&gt;</pre><pre>$&gt; $KAFKA_HOME/bin/connect-standalone.sh config/connect-standalone.properties config/connector-web3-events-source.properties</pre><p>Subscribe to the event Kafka topic to see the fetched event log data in real-time.</p><h3>Run the connector in distributed mode</h3><p>To run the Kafka web3 source connectors in distributed mode, you can download the connector jar from the release section of the project or from target folder (if you are building from source).</p><pre><a href="https://github.com/satran004/kafka-web3-connector/releases/">https://github.com/satran004/kafka-web3-connector/releases/</a></pre><p><strong>Links :</strong></p><ul><li>Kafka Web3 Connector Project — <a href="https://github.com/satran004/kafka-web3-connector">https://github.com/satran004/kafka-web3-connector</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1310c83decd0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Aion4j Tips —Unit Test your Avm Java Smart Contract with Spock Framework]]></title>
            <link>https://satran004.medium.com/aion4j-tips-unit-test-your-avm-java-smart-contract-with-spock-framework-a878a0d6fb7a?source=rss-3bb19096c001------2</link>
            <guid isPermaLink="false">https://medium.com/p/a878a0d6fb7a</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[smart-contracts]]></category>
            <category><![CDATA[unit-testing]]></category>
            <category><![CDATA[aion]]></category>
            <category><![CDATA[spock-framework]]></category>
            <dc:creator><![CDATA[Satya]]></dc:creator>
            <pubDate>Sun, 30 Jun 2019 10:26:34 GMT</pubDate>
            <atom:updated>2019-06-30T10:32:13.504Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f9mpituyvC1Ww3B2T6v6aA.png" /></figure><p>In this post, I am going to explain how to use Spock Framework to unit test Java smart contract. <a href="http://spockframework.org/">Spock</a> is a Groovy based testing framework and an alternative to the traditional JUnit framework. By making use of Groovy, Spock introduces new and expressive ways of testing Java applications.</p><p>In this post, we will be covering a basic Spock test and a test using Spock’s “Data Driven Testing” feature. To know more about Spock Framework, you can check Spock’s <a href="http://spockframework.org/spock/docs/1.3/all_in_one.html">documentation</a>.</p><p>Another goal of this post is to showcase how easily any existing JVM frameworks or tools can be used in Smart Contract development.</p><blockquote>If you would like to know how to write and run JUnit test for your Java smart contract, you can check this <a href="https://blog.aion.network/debugging-avm-contracts-4a3256e86221">blog</a> written by Shidokth.</blockquote><p>In short, Avm provides a JUnit rule called “AvmRule” which can be used to test contracts on an embedded Avm. We are going to use this class in this post.</p><p>The source code for this sample can be found over <a href="https://github.com/satran004/avm-samples/tree/master/SumContract-spock-sample">on GitHub</a>.</p><p><strong>a. Create a Java Contract Project</strong></p><p>To create a Java smart contact project with IntelliJ IDE and <a href="https://bloxbean.com">BloxBean</a>’s Aion4j Plugin, you can follow the steps on this Aion <a href="https://docs.aion.network/docs/intellij-plugin">doc page</a>.</p><p>In this post, we will be writing a very simple contract to demonstrate how to setup Spock unit test. We are going to create a smart contract which returns the sum of two numbers. I have intentionally kept it very simple, as the goal is to show case the usage of Spock framework for contract testing, not how to write Java contract.</p><p><strong>b. Remove default generated smart contract files</strong></p><p>Once you have created a new Java smart contract project in IntelliJ, you can remove the default generated contract “HelloAvm.java” (under src/main/java folder) and the corresponding test class, “HelloAvmRuleTest.java” (under src/test/java folder).</p><p><strong>c. pom.xml change</strong></p><ol><li>Open pom.xml file and add the following dependencies for Spock framework.</li></ol><pre>&lt;<strong>dependency</strong>&gt;<br>    &lt;<strong>groupId</strong>&gt;org.spockframework&lt;/<strong>groupId</strong>&gt;<br>    &lt;<strong>artifactId</strong>&gt;spock-core&lt;/<strong>artifactId</strong>&gt;<br>    &lt;<strong>version</strong>&gt;1.3-groovy-2.4&lt;/<strong>version</strong>&gt;<br>    &lt;<strong>scope</strong>&gt;test&lt;/<strong>scope</strong>&gt;<br>&lt;/<strong>dependency</strong>&gt;<br>&lt;<strong>dependency</strong>&gt;<br>    &lt;<strong>groupId</strong>&gt;org.codehaus.groovy&lt;/<strong>groupId</strong>&gt;<br>    &lt;<strong>artifactId</strong>&gt;groovy-all&lt;/<strong>artifactId</strong>&gt;<br>    &lt;<strong>version</strong>&gt;2.4.17&lt;/<strong>version</strong>&gt;<br>    &lt;<strong>scope</strong>&gt;test&lt;/<strong>scope</strong>&gt;<br>&lt;/<strong>dependency</strong>&gt;</pre><p>2. We need to include the <em>gmavenplus </em>plugin in order to be able to compile and run our Spock groovy test scripts. Add the following plugin in plugins section.</p><pre>&lt;build&gt;<br>  &lt;plugins&gt;<br>    ...<br>    ...<br>    <br>    &lt;<strong>plugin</strong>&gt;<br>       &lt;<strong>groupId</strong>&gt;org.codehaus.gmavenplus&lt;/<strong>groupId</strong>&gt;<br>       &lt;<strong>artifactId</strong>&gt;gmavenplus-plugin&lt;/<strong>artifactId</strong>&gt;<br>       &lt;<strong>version</strong>&gt;1.5&lt;/<strong>version</strong>&gt;<br>       &lt;<strong>executions</strong>&gt;<br>        &lt;<strong>execution</strong>&gt;<br>            &lt;<strong>goals</strong>&gt;<br>                &lt;<strong>goal</strong>&gt;compile&lt;/<strong>goal</strong>&gt;<br>                &lt;<strong>goal</strong>&gt;testCompile&lt;/<strong>goal</strong>&gt;<br>            &lt;/<strong>goals</strong>&gt;<br>        &lt;/<strong>execution</strong>&gt;<br>      &lt;/<strong>executions</strong>&gt;<br>    &lt;/<strong>plugin&gt;<br>  &lt;/plugins&gt;<br></strong>&lt;/build&gt;</pre><p><strong>d. Create contract Java file</strong></p><p>Create a new Java class for our contract under source package. Let’s call it “<em>SumContract.java</em>”.</p><p>Add the following content to the contract source file.</p><pre><strong>import </strong>org.aion.avm.tooling.abi.Callable;<br><br><strong>public class </strong>SumContract {<br><br>    @Callable<br>    <strong>public static int </strong>sum(<strong>int </strong>i, <strong>int </strong>j) {<br>        <strong>return </strong>i + j;<br>    }<br>    <br>}</pre><p><strong><em>Note:</em></strong><em> Don’t replace the package section in the original file.</em></p><p>This contract has only one method <strong>“sum”</strong> which returns the sum of two numbers.</p><p><em>The </em><strong><em>@Callable</em></strong><em> annotation needs to be there for all public contract methods.</em></p><p><strong>e. Contract main class in pom.xml</strong></p><p>Update pom.xml to include SumContract class name as <strong>contract.main.class</strong>. To do that, edit <strong>&lt;contract.main.class&gt;</strong> element to include fully qualified SumContract class name.</p><p>Example:</p><pre>&lt;properties&gt;<br>...</pre><pre>&lt;<strong>contract.main.class</strong>&gt;org.aion4j.avm.sample.SumContract&lt;/<strong>contract.main.class</strong>&gt;</pre><pre>&lt;/properties&gt;</pre><p><strong>e. Create test class</strong></p><p>We will be using Groovy to write our Spock test script.</p><ul><li>Create a folder called “groovy” under <em>src/test</em> folder.</li><li>Create a new Groovy script, <em>“SumContractTest.groovy”</em> under src/test/groovy folder.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/270/1*nZqOKBCky4vF1bGuE9s6mg.png" /></figure><p><strong><em>Note:</em></strong><em> Please make sure that the test groovy class name ends with “Test”, so that the Spock test script will be picked up during test run by maven sunfire plugin.</em></p><ul><li><em>“SumContractTest”</em> groovy class should extend <strong><em>spock.lang.Specification</em></strong><em>. </em>Each Spock class must extend this in order to make the framework available to it.</li></ul><pre><strong>class </strong>SumContractTest <strong>extends </strong>Specification {</pre><pre>}</pre><ul><li>Let’s add AvmRule as a ClassRule in our test class. Define a setup() which will be running before every test method.</li></ul><pre>@ClassRule<br>@Shared<br><strong>private </strong>AvmRule <strong>avmRule </strong>= <strong>new </strong>AvmRule(<strong>true</strong>);<br><strong>private </strong>Address <strong>from</strong>;<br><strong>private </strong>Address <strong>dappAddr</strong>;<br><br><strong>def </strong>setup() {<br>    <strong>from </strong>= <strong>avmRule</strong>.getPreminedAccount();<br>    <strong>byte</strong>[] dapp = <strong>avmRule</strong>.getDappBytes(org.aion4j.avm.sample.SumContract, <strong>null</strong>);<br>    <strong>dappAddr </strong>= <strong>avmRule</strong>.deploy(<strong>from</strong>, BigInteger.<strong><em>ZERO</em></strong>, dapp).getDappAddress();<br>}</pre><p>Spock understands @org.junit.ClassRule annotations on @Shared fields. In setup(), we are deploying our SumContract class to an embedded Avm. This method gets called before every test method run.</p><ul><li>Our first test method checks the sum of two numbers, 4 and 5.</li></ul><pre><strong>def &quot;4 plus 5 should be equal to 9&quot;</strong>() {</pre><pre>    <strong>when</strong>:<br>        <strong>byte</strong>[] txData = ABIUtil.<em>encodeMethodArguments</em>(<strong>&quot;sum&quot;</strong>, 5, 4);<br>        AvmRule.ResultWrapper result = <strong>avmRule</strong>.call(<strong>from</strong>, <strong>dappAddr</strong>, BigInteger.<strong><em>ZERO</em></strong>, txData);<br>        <strong>int </strong>sum = Integer.<em>parseInt</em>(String.<em>valueOf</em>(result.getDecodedReturnData()));<br><br>    <strong>then</strong>:<br>        sum == 9;<br><br>}</pre><p>In the above test method, there are two blocks with labels “<strong>when</strong>” and “<strong>then</strong>”.</p><p>Inside “<strong>when</strong>” block, we are <br>- Preparing method call transaction data<br>- Calling contract method through AvmRule.call()<br>- Getting the decoded result</p><p>Inside “<strong>then</strong>” block, the actual result is compared with the expected result.</p><p><em>According to Spock’s documentation,</em></p><blockquote>Spock has built-in support for implementing each of the conceptual phases of a feature method. To this end, feature methods are structured into so-called <em>blocks</em>. Blocks start with a label, and extend to the beginning of the next block, or the end of the method. There are six kinds of blocks: setup, when, then, expect, cleanup, and where blocks. Any statements between the beginning of the method and the first explicit block belong to an implicit setup block.</blockquote><blockquote>In Spock, what we refer to as a <em>feature </em>is somewhat synonymous to what we see as a <em>test </em>in JUnit.</blockquote><ul><li>Let’s write out second feature method. The second test shows one of the powerful feature of Spock called <strong>“Data Driven Testing”</strong>.</li></ul><pre><strong>def &quot;a plus b should equal to expected&quot; </strong>(<strong>int </strong>a, <strong>int </strong>b, <strong>int </strong>expected) {</pre><pre>    <strong>given</strong>:<br>        <strong>byte</strong>[] txData = ABIUtil.<em>encodeMethodArguments</em>(<strong>&quot;sum&quot;</strong>, a, b);<br>        AvmRule.ResultWrapper result = <strong>avmRule</strong>.call(<strong>from</strong>, <strong>dappAddr</strong>, BigInteger.<strong><em>ZERO</em></strong>, txData);<br>        <strong>int </strong>sum = Integer.<em>parseInt</em>(String.<em>valueOf</em>(result.getDecodedReturnData()));<br><br>    <strong>expect</strong>:<br>        sum == expected<br><br>    <strong>where</strong>:<br>        a | b | expected<br>        4 | 6 | 10<br>        9 | 2 | 11<br>        23| 21| 44<br><br>}</pre><blockquote>Essentially, <strong>data driven testing is when we test the same behavior multiple times with different parameters and assertions</strong>. A example of this would be testing the sum operation. Depending on the various permutations of operands, the result will be different.</blockquote><p>This test method takes three parameters a (first operand), b (second operand) and expected (expected sum value).</p><p>In “<strong>given</strong>” block, the transaction data is prepared and contract method is called through AvmRule.call(). <br>In “<strong>expect</strong>” block, the returned result is compared with the expected value.<br>In “<strong>where</strong>” block, we are providing a datatable for our test with different operand pairs and corresponding expected results.</p><p>As we can see, we just have a straightforward and expressive Data table containing all our parameters. The test is expressive, with a human-readable name, and pure <em>expect </em>and <em>where </em>block to break up the logical sections.</p><p>This is one of the advantage of Spock when compared to JUnit because the way Spock implements parameterized testing.</p><p>Spock also has it’s own mocking framework. So in case you want to use mock/stubs inside your tests, you don’t need to use a separate mocking library.</p><p><strong>Run Tests</strong></p><ul><li>Build your project and run tests</li></ul><p>You can now run <em>“mvn clean install”</em> to build and run your tests. You can also directly run these tests from IntelliJ’s editor.</p><p>In this post, we have just scratched the surface. For more info about Spock framework, you can check Spock’s <a href="http://spockframework.org/spock/docs/1.3/all_in_one.html">documentation</a> page.</p><p><strong>Resources</strong></p><ol><li>Sample Code : <a href="https://github.com/satran004/avm-samples/tree/master/SumContract-spock-sample">https://github.com/satran004/avm-samples/tree/master/SumContract-spock-sample</a></li><li>Spoke Framework : <a href="http://spockframework.org/">http://spockframework.org/</a></li><li>AVM GitHub : <a href="https://github.com/aionnetwork/avm">https://github.com/aionnetwork/avm</a></li><li>BloxBean : <a href="https://www.bloxbean.com/">https://www.bloxbean.com/</a></li><li>Avm Smart Contract with IntelliJ IDE: <a href="https://docs.aion.network/docs/intellij-plugin">https://docs.aion.network/docs/intellij-plugin</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a878a0d6fb7a" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>