<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: flex</title>
    <description>The latest articles on DEV Community by flex (@kungfuflex).</description>
    <link>https://dev.to/kungfuflex</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2492406%2F5c477af4-2236-4feb-a35b-ae0b1096a9f9.jpeg</url>
      <title>DEV Community: flex</title>
      <link>https://dev.to/kungfuflex</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kungfuflex"/>
    <language>en</language>
    <item>
      <title>SUBFROST: Utilizing BTC in Metaprotocol Space</title>
      <dc:creator>flex</dc:creator>
      <pubDate>Thu, 12 Dec 2024 00:18:09 +0000</pubDate>
      <link>https://dev.to/kungfuflex/subfrost-wbtc-in-metaprotocol-space-13ec</link>
      <guid>https://dev.to/kungfuflex/subfrost-wbtc-in-metaprotocol-space-13ec</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;tldr: native Bitcoin restaking protocols are coming&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Over the past several years, a great deal of my research and development effort has been in synthetics, specifically ones backed by Bitcoin. Such assets allow us to utilize native Bitcoin currency within the greater ecosystem of blockchain finance, and are of paramount importance. Generally, projects which aspire to connect Bitcoin to external consensus engines accomplish this using a multisignature custody mechanism, with supplementary incentive mechanisms which, theoretically, create decentralized governance and oversight.&lt;/p&gt;

&lt;p&gt;Developing a system like this can be burdensome, but it can be accomplished. More often it is not without some tradeoffs or limited trust assumptions. The final form of such a product should be thought of as an &lt;em&gt;L0&lt;/em&gt;, since in spirit it should belong to a consensus engine that allows us to transfer Bitcoin into another representation on a separate L1 or L2.&lt;/p&gt;

&lt;p&gt;Projects in the Bitcoin L2 space often feature an L0 subsystem of some kind to facilitate bridging of value on and off an off-chain consensus program.&lt;/p&gt;

&lt;h2&gt;
  
  
  BTC on ALKANES
&lt;/h2&gt;

&lt;p&gt;Unlike a scenario where we bridge to other blockchain systems or EVM, if we want to bridge to/from a metaprotocol on the Bitcoin L1 layer, we get the benefit of a shared space for asset representations, which coexist on the same L1 data layer.&lt;/p&gt;

&lt;p&gt;On ALKANES, where we have WASM smart contract assets, we can have something like this on Bitcoin L1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Token&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;SyntheticBitcoin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SUBFROST BTC"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"frBTC"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Source: &lt;a href="https://github.com/subfrost/frBTC/tree/main/alkanes/fr-btc/src/lib.rs" rel="noopener noreferrer"&gt;https://github.com/subfrost/frBTC/tree/main/alkanes/fr-btc/src/lib.rs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This could get good.&lt;/p&gt;

&lt;p&gt;In fact, if we are bridging Bitcoin to the ALKANES metaprotocol to a wrapped representation, we can actually design an alkane smart contract for the synthetic, where Bitcoin can be wrapped atomically and without trust assumptions. Since the action of wrapping Bitcoin to an alkane happens as part of a normal &lt;a href="https://github.com/kungfuflex/alkanes-rs/wiki/Background:-PROTORUNES" rel="noopener noreferrer"&gt;protorunes&lt;/a&gt; protocol message, it can be composed into other intents which actually use the Bitcoin synthetic and &lt;em&gt;do&lt;/em&gt; something with it, all in the same Bitcoin transaction.&lt;/p&gt;

&lt;p&gt;Additionally, the alkane for our synthetic can perform all the accounting necessary for a federated multisignature custodian to handle &lt;em&gt;unwrapping&lt;/em&gt; back to Bitcoin. Even if we cannot actually unlock Bitcoin spends from the metaprotocol layer, we can use the metaprotocol to signal the signing group to perform this function.&lt;/p&gt;

&lt;p&gt;That's a little abstract, but the easy way to put it is that wrapping Bitcoin to an alkane is instant, and unwrapping requires the decentralized multisig. The decentralized multisig reads directly from the alkane to know who burns synthetics and should receive Bitcoin.&lt;/p&gt;

&lt;p&gt;SUBFROST is what we call this decentralized custodian and can exist as a very lightweight layer on top of an ALKANES indexer, which simply listens for new blocks and coordinates a small ring of signers which custody and redeem synthetic metaprotocol BTC back to native BTC currency. The ALKANES metaprotocol does all the work for us, so we do not need a heavy-duty consensus engine to coordinate the active group of signers to agree on what messages should be signed over the p2p channel.&lt;/p&gt;

&lt;p&gt;Signers just run the ALKANES indexer and SUBFROST software, and thus the consensus model for our L0 exists purely as an extension of the Bitcoin protocol itself.&lt;/p&gt;

&lt;p&gt;This is how we can activate Bitcoin in decentralized programs of any kind, to the limit of what we can develop on the WASM execution layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  frBTC Usage
&lt;/h2&gt;

&lt;p&gt;The repository for frBTC (SUBFROST BTC) is available at:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/subfrost/frBTC" rel="noopener noreferrer"&gt;https://github.com/subfrost/frBTC&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Examples of minting and burning frBTC are available in the test suite, but a web application will be available for ease of access to synthetics.&lt;/p&gt;

&lt;p&gt;A frBTC asset challenges the problem surface of building on Bitcoin L1 as we have traditionally seen it:&lt;/p&gt;

&lt;p&gt;In a single transaction, it becomes possible to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Swap BTC to a Bitcoin native stablecoin asset directly via AMM, at the desired slippage tolerance.&lt;/li&gt;
&lt;li&gt;Deposit BTC into a privacy pool, similar in function to what we see possible on Zcash&lt;/li&gt;
&lt;li&gt;Use BTC as collateral to mint synthetic stablecoins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stake BTC&lt;/strong&gt; (look out for SUBFROST protocol token announcements)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last item here we will discuss in a future article as we approach SUBFROST on mainnet, but it is something of a long saga of development from myself to make this possible.&lt;/p&gt;

&lt;p&gt;All of this, for something which seems so simple in ethos: retain exposure to Bitcoin, but use it to earn more Bitcoin, passively. The difficult part is when we would like to do this with zero (or otherwise minimal) protocol risk.&lt;/p&gt;

&lt;p&gt;It is my life's work to see such a protocol come to exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Follow along:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://x.com/judoflexchop" rel="noopener noreferrer"&gt;https://x.com/judoflexchop&lt;/a&gt;&lt;br&gt;
&lt;a href="https://x.com/bc1SUBFROST" rel="noopener noreferrer"&gt;https://x.com/bc1SUBFROST&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Weapons-grade Metaprotocols on METASHREW</title>
      <dc:creator>flex</dc:creator>
      <pubDate>Fri, 29 Nov 2024 21:47:04 +0000</pubDate>
      <link>https://dev.to/kungfuflex/weapons-grade-metaprotocols-on-metashrew-262k</link>
      <guid>https://dev.to/kungfuflex/weapons-grade-metaprotocols-on-metashrew-262k</guid>
      <description>&lt;p&gt;For those who have attempted to extend Bitcoin via the metaprotocol layer, or even just write software to index metaprotocols such as ordinals or BRC-20, you may be aware of the scope of the problem. Most traditional metaprotocols we've seen are easy enough to understand a schema for, as far as the rules to process a single block to update the state of an index.&lt;/p&gt;

&lt;p&gt;For ordinals, parsing a block to track the owner of an inscription by a given sequence number, may require program flow such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Process each transaction, and if there is a witness stack with an ord-prefixed inscription structure, assign a sequence number and insert into the database&lt;/li&gt;
&lt;li&gt;Compute ranges of sats as they are spent onto new outputs, removing their original positions in the set of spendable UTXOs paid into the transaction, and assigning partition ranges instead to UTXOs which are created&lt;/li&gt;
&lt;li&gt;Associate sequence numbers for updated owners to their new computed address, based on UTXOs which are able to spend inscriptions associated with a given number&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The scope of the ord indexer is greater than this, but this is perhaps one example of a means to design a program which can, when queried, provide a user interface with data about ownership for a given inscription.&lt;/p&gt;

&lt;p&gt;These rules are simple enough, but there is much more you have to deal with if you are writing an indexer program.&lt;/p&gt;

&lt;p&gt;Some of this work includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieving block data from a desired start block height and replaying until the block tip&lt;/li&gt;
&lt;li&gt;At tip, wait for new blocks to appear, and when they do, process indexer rules for the new block and update the database&lt;/li&gt;
&lt;li&gt;Maintain database connections and implement any query language needed to work against your data store&lt;/li&gt;
&lt;li&gt;Detect a reorg and, if needed, roll back state of the index&lt;/li&gt;
&lt;li&gt;Provide an API to read from the indexer and render as JSON or any desired format&lt;/li&gt;
&lt;li&gt;Retrieve historical state of the index, if we want a view into the dataset at an earlier state&lt;/li&gt;
&lt;li&gt;If needed, compute integrity checks of the dataset to ensure there is no corruption and that the state of the index is consistent with others running the same program, without explicitly rebuilding the index from the beginning. Sometimes this is accomplished with merklized tree structures, for example&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is more that one may want to do, but these are some examples of problems that would have to be solved for anyone attempting to index a metaprotocol with software built from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  METASHREW
&lt;/h2&gt;

&lt;p&gt;The METASHREW framework is designed to simplify the task of implementing a metaprotocol, and makes it possible to architect a metaprotocol as intensive as ALKANES. When you build a metaprotocol on METASHREW, instead of building an indexer from scratch, you strictly build a single WASM program, written in any language that is an LLVM frontend, such as Rust.&lt;/p&gt;

&lt;p&gt;METASHREW can load a WASM program built with metashrew bindings and run it once for each block in series, automatically detecting reorgs, rolling back state, and processing the corrected block history to correct the state of the index. We choose WASM because it is a portable format for a binary which is platform-independent, where we can deterministically compile the same WASM file to run with identical behavior, with matching compiler software and a version of the source code for the indexer.&lt;/p&gt;

&lt;p&gt;With a METASHREW program, it is possible to verify the complete index by simply hashing or otherwise computing a checksum of the WASM program expressing the index, then comparing it to a known value. The same WASM file against the same blockdata will produce the same index in the backend database.&lt;/p&gt;

&lt;p&gt;A METASHREW program simply handles the processing of a single block as it seen during a sync of block history from the desired start height. The program is provided a handle to an arbitrary k/v store provided by the runtime. For normal usage of METASHREW we encourage the use of &lt;code&gt;metashrew-keydb&lt;/code&gt; provided in the repository, which uses the &lt;em&gt;KeyDB&lt;/em&gt; database engineered by the Snapchat team. This database allows us to perform I/O from the indexer directly over a UNIX socket, and it will allow us to do the majority of our work entirely in-memory, if we have a system with a large amount of resources available. This helps with METASHREW programs since we attempt to reuse a local cache of the k/v pairs we store with each block, to avoid context switching out of the WASM program to its most minimal frequency while we rapidly build an index.&lt;/p&gt;

&lt;p&gt;METASHREW provides an RPC layer which is designed to be parallelized. View functions are just normal exports from a WASM program, which use the same runtime functions within the indexer environment to access inputs provided with the RPC call.&lt;/p&gt;

&lt;p&gt;In ALKANES, we provide a view function to simulate an arbitrary transaction with any mocked inputs of value or cellpack we provide. It is technically possible to execute sandboxed WASM directly within this view function if a contract deployment is simulated against this view function. In this way, a potentially complex view of ALKANES state can be constructed with a view function call, and if the RPC layer is properly multiprocessed on the systems providing &lt;code&gt;metashrew-view&lt;/code&gt; service running the &lt;em&gt;alkanes.wasm&lt;/em&gt;, we can horizontally scale the rendering model of a user application. This makes it possible, for example, to render graphics or assemble/transform PNG or SVG images, to build more immersive NFTs. In fact, the &lt;code&gt;alkanes-rs&lt;/code&gt; repository ships a minimal example of an NFT on ordinals, which we have coined &lt;em&gt;orbitals&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Below is the source code for the most minimal implementation of an orbital:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;alkanes_runtime&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AlkaneResponder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StoragePointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;token&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;alkanes_support&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;parcel&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AlkaneTransfer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;response&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CallResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;anyhow&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;anyhow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;hex_lit&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;metashrew_support&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;compat&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;to_arraybuffer_layout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to_passback_ptr&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;metashrew_support&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;index_pointer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;KeyValuePointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Default)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;Orbital&lt;/span&gt;&lt;span class="p"&gt;(());&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Token&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Orbital&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1x1 Ape (Very f** rare)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"APE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Orbital&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;total_supply_pointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;StoragePointer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;StoragePointer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_keyword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/totalsupply"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;total_supply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;u128&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.total_supply_pointer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.get_value&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u128&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;set_total_supply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.total_supply_pointer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.set_value&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u128&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;observe_initialization&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;initialized_pointer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;StoragePointer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_keyword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/initialized"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;initialized_pointer&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;initialized_pointer&lt;/span&gt;&lt;span class="py"&gt;.set_value&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;anyhow!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"already initialized"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// in this reference implementation, we return a 1x1 PNG&lt;/span&gt;
        &lt;span class="c1"&gt;// NFT data can be anything, however, and it can be computed, if we want a dynamic effect&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;hex!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"89504e470d0a1a0a0000000d494844520000000100000001010300000025db56ca00000003504c5445000000a77a3dda0000000174524e530040e6d8660000000a4944415408d76360000000020001e221bc330000000049454e44ae426082"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;AlkaneResponder&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Orbital&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;CallResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.context&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="py"&gt;.inputs&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CallResponse&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="py"&gt;.incoming_alkanes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.observe_initialization&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.set_total_supply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="py"&gt;.alkanes&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AlkaneTransfer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="py"&gt;.myself&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1u128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="mi"&gt;99&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.into_bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.symbol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.into_bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="mi"&gt;101&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.total_supply&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_le_bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.data&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"unrecognized opcode"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;__execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;to_arraybuffer_layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;Orbital&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.run&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nf"&gt;to_passback_ptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Source: &lt;a href="https://github.com/kungfuflex/alkanes-rs/tree/main/crates/alkanes-std-orbital/src/lib.rs" rel="noopener noreferrer"&gt;https://github.com/kungfuflex/alkanes-rs/tree/main/crates/alkanes-std-orbital/src/lib.rs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We reserve opcode 1000 for the &lt;code&gt;data&lt;/code&gt; view function, which in this case returns a static bytearray, but could in theory be used to pack or construct any dynamic bytearray or imagedata blob, since the view function to simulate transaction messages in ALKANES is run with a very large fuel limit and capable of long running compute.&lt;/p&gt;

&lt;p&gt;The METASHREW architecture provides a means to run this kind of compute in an entirely separate process or container, since the data is decoupled from the indexer, and the indexer is decoupled from the view layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compatibility
&lt;/h2&gt;

&lt;p&gt;METASHREW was initially designed as an electrum fork, but I since rewrote it from scratch in order to design an indexer routine that purely operates over the RPC port, to make it more universal for use against Bitcoin compatible interfaces other than Bitcoin itself, including DOGE or DOGE forks.&lt;/p&gt;

&lt;p&gt;The libraries for METASHREW are now most up to date as they appear in the Rust monorepo for alkanes-rs, including the pure bindings to METASHREW and also &lt;code&gt;metashrew-support&lt;/code&gt; which is an environment-agnostic support library for lower level operations frequently done both in the ALKANES indexer as well as alkane smart contracts themselves.&lt;/p&gt;

&lt;p&gt;This includes my own &lt;code&gt;AuxpowBlock&lt;/code&gt; structure and implementation, which provides a replacement for the usual &lt;code&gt;rust-bitcoin&lt;/code&gt; library, one that can properly parse merge mined blockchains with a slightly modified structure, and requires an extension to the usual Bitcoin block parsing logic.&lt;/p&gt;

&lt;p&gt;The implementation of &lt;code&gt;AuxpowBlock&lt;/code&gt; provides a convenience method to convert back into a &lt;code&gt;bitcoin::Block&lt;/code&gt; structure which drops the Auxpow metadata if we do not need it for our indexer. To index ALKANES, we do not use it.&lt;/p&gt;

&lt;p&gt;The result is that the pure Rust implementation of ALKANES, and any other metaprotocol forked from it or built on METASHREW with the support libraries we provide, can run on Bitcoin mainnet, or the many forks we have seen gain some traction in the wild such as Luckycoin, Bellscoin.&lt;/p&gt;

&lt;p&gt;And yes, this means we also will have a genesis block for our DOGE L1 smart contracts as well. These genesis constants will likely change as they currently appear in the build system but we will see a canonical ALKANES appear on DOGE L1 on protorunes subprotocol ID 1, sometime following release on mainnet Bitcoin.&lt;/p&gt;

&lt;p&gt;I will explain in a future post about why this is a good thing.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>assemblyscript</category>
      <category>bitcoin</category>
      <category>ordinals</category>
    </item>
    <item>
      <title>ALKANES: Smart Contracts on Bitcoin UTXOs</title>
      <dc:creator>flex</dc:creator>
      <pubDate>Thu, 28 Nov 2024 00:08:05 +0000</pubDate>
      <link>https://dev.to/kungfuflex/alkanes-smart-contracts-on-bitcoin-utxos-4k28</link>
      <guid>https://dev.to/kungfuflex/alkanes-smart-contracts-on-bitcoin-utxos-4k28</guid>
      <description>&lt;h2&gt;
  
  
  What is ALKANES?
&lt;/h2&gt;

&lt;p&gt;ALKANES is an application layer built directly on Bitcoin where individuals or teams can deploy smart contracts to Bitcoin L1. ALKANES is one example of a &lt;em&gt;metaprotocol&lt;/em&gt;, which is a set of rules and definitions to process block history in a blockchain system, to add additional features and concepts built on its data.&lt;/p&gt;

&lt;p&gt;ALKANES is my conception of a metaprotocol project which inherits structures and design patterns from the very popular &lt;em&gt;ordinals&lt;/em&gt; and &lt;em&gt;runes&lt;/em&gt; metaprotocol projects, authored by Casey Rodarmor. From ordinals, we use the concept of the &lt;em&gt;inscription envelope&lt;/em&gt;, but a more minimal variant of it, which we will simply call the &lt;em&gt;witness envelope&lt;/em&gt;. We use the witness envelope, at minimum, to deploy &lt;code&gt;*.wasm.gz&lt;/code&gt; files to the Bitcoin blockchain, after which they can be transacted against as smart contract programs, using any combination of inputs of value, data, and the context of the transaction itself.&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;*.wasm.gz&lt;/code&gt; file format of ALKANES smart contracts, we can build smart contracts in a language like Rust, and build contracts that are very much within the size constraints we must work within, when deploying to something like the Bitcoin blockchain. In fact, as an experiment, I &lt;a href="https://github.com/kungfuflex/noir" rel="noopener noreferrer"&gt;forked the noir VM&lt;/a&gt; to a slightly modified version that would play nice with the alkanes build system, and I used it to do a minimal build of an alkane smart contract capable of verifying a proof for a zk-circuit compiles with the AZTEC noir project. The final binary filesize was 550kb, but when gzipped to a &lt;code&gt;*.wasm.gz&lt;/code&gt;, was merely 150kb.&lt;/p&gt;

&lt;p&gt;This means there is a world of possibilities for what we can accomplish on Bitcoin as it exists today.&lt;/p&gt;

&lt;p&gt;For its regular operation, ALKANES inherits from the runes metaprotocol as well as ordinals. We do in fact use the &lt;code&gt;Runestone&lt;/code&gt; structure as it is defined in the runes specification, but in a way that is harmless to indexers tracking the state of runes, and also, in a way where it is possible to compose transfers of runes and alkanes as part of a swap transaction, which has the correct effect on indexers tracking the state of either metaprotocol.&lt;/p&gt;

&lt;p&gt;Inheriting from these two metaprotocols means we have a lot of open source software in the ecosystem already that we can tap into. I ported modified versions of &lt;code&gt;@magiceden-oss/runestone-lib&lt;/code&gt; and also &lt;code&gt;micro-ordinals&lt;/code&gt; from the desk of the prolific &lt;a href="https://github.com/paulmillr" rel="noopener noreferrer"&gt;https://github.com/paulmillr&lt;/a&gt;, into the alkanes TypeScript repository here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kungfuflex/alkanes" rel="noopener noreferrer"&gt;https://github.com/kungfuflex/alkanes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This library is usable for constructing transactions that can both deploy and transact against alkanes smart contracts, and an example of a complete program flow can be found here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kungfuflex/alkanes/tree/main/integration/genesis.spec.ts" rel="noopener noreferrer"&gt;https://github.com/kungfuflex/alkanes/tree/main/integration/genesis.spec.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this repository I have also written a &lt;code&gt;docker-compose.yaml&lt;/code&gt; which provides a full regtest environment and supplementary database, usable to run the integration test mentioned above, but also to build applications! Indeed, it is possible to build applications that are even more expressive than what we have seen in traditional DeFi systems, using the combined power of LLVM and the paritytech &lt;code&gt;wasmi&lt;/code&gt; interpreter / WebAssembly runtime, entirely on native Bitcoin L1.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can an ALKANE do?
&lt;/h2&gt;

&lt;p&gt;An alkane smart contract is very much a Bitcoin native construct. First and foremost, it is always a token, whether or not it actually does anything with its own balance sheet. It can hold a balance sheet of itself as well as other alkanes, the same that a UTXO can hold alkanes or runes. This idea actually resonated with me when Andre Cronje explained to me his thesis on DeFi many years ago, applied to his vision for YFI.&lt;/p&gt;

&lt;p&gt;In simple terms: "make every contract an ERC20."&lt;/p&gt;

&lt;p&gt;This happens to provide a consistent model for interoperability that helped DeFi take form, and I wanted this to exist as a primitive within ALKANES, bearing the improvement that a transfer of assets always invokes the code of the recipient, so we can always do everything in one transaction in the UX we build.&lt;/p&gt;

&lt;p&gt;What else?&lt;/p&gt;

&lt;p&gt;An alkane can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check balances of alkanes&lt;/li&gt;
&lt;li&gt;Read/write to storage for the alkane&lt;/li&gt;
&lt;li&gt;Check how much fuel is left to execute code&lt;/li&gt;
&lt;li&gt;Access the transaction bytes of the Bitcoin transaction executing the alkane

&lt;ul&gt;
&lt;li&gt;If it is present, read one or more witness envelope structures present with the transaction, when we need to send a transaction with large payloads such as a zk proof, merkle proof, or &lt;em&gt;&lt;a href="https://github.com/kungfuflex/shorcell" rel="noopener noreferrer"&gt;quantum safe signature&lt;/a&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Compute the address that the output will be spent to, or otherwise check the Bitcoin vmscript on the output that the output of some alkanes action will end up on, if we want to check for covenants, enforce conditions on spending, or other novel uses of OP_CAT even. Building on UTXOs mean we have the benefit of being able to extend Bitcoin scripting as we normally use it, and get the benefit of new opcodes as they occur, if they do.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Access the entire block bytes which the current transaction is running within

&lt;ul&gt;
&lt;li&gt;Programmatically determine who the miner of the current block is (we may want to bribe this individual in our transaction, perhaps)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Act upon the transfer of value sent with the transaction, in terms of the combined balance sheet of alkanes spent into the action&lt;/li&gt;

&lt;li&gt;Access the ID for the alkane calling the current alkane, if they call each other&lt;/li&gt;

&lt;li&gt;Access the ID for the alkane executing code&lt;/li&gt;

&lt;li&gt;Call another alkane&lt;/li&gt;

&lt;li&gt;Delegate to another alkane (upgradeability, libraries)&lt;/li&gt;

&lt;li&gt;Call another alkane but prevent side effects&lt;/li&gt;

&lt;li&gt;Get the next sequence number, usable also if an alkane is created by an alkane in a transaction and its ID should be computed&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;I tried not to get too much fancier than this, since everything else should be doable in userspace.&lt;/p&gt;

&lt;h2&gt;
  
  
  Indexer
&lt;/h2&gt;

&lt;p&gt;The indexer for ALKANES itself actually builds to WASM. So, it is true that the WASM VM for an alkane, is itself, built to WASM. The reason it was possible to build a metaprotocol that was deterministic and which meets the strict integrity requirements of a metaprotocol indexer built on top of a blockchain consensus model, is because we have something like &lt;em&gt;metashrew&lt;/em&gt;, which is a generic metaprotocol indexer stack capable of running WASM programs expressing a metaprotocol.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sandshrewmetaprotocols/metashrew" rel="noopener noreferrer"&gt;https://github.com/sandshrewmetaprotocols&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Metashrew is itself an extensive project and warrants a separate article to properly introduce, but the easy way to put it is that it is a software stack that reduces the problem of architecting a complex metaprotocol, by a considerable degree.&lt;/p&gt;

&lt;p&gt;The ALKANES indexer program is a pure Rust project built with bindings to the metashrew runtime. To verify that the version of the ALKANES indexer, and therefore the index it builds, is consistent with what is expected, it is simple enough to just compare the SHA256 hash of the WASM binary for &lt;code&gt;alkanes.wasm&lt;/code&gt; to a known value. I have actually had to do this quite a few times for easy sanity checks while debugging in the indexer WASM. Very convenient.&lt;/p&gt;

&lt;p&gt;The metashrew software comes with &lt;em&gt;metashrew-view&lt;/em&gt;, which is a minimal JSON-RPC service that will execute the same WASM for the indexer but in a way where there cannot be side effects of calling function. The process can be parallelized and provides a way you can multiprocess potentially heavy compute to render the state or a simulated effect of the indexer. In ALKANES we actually export a &lt;code&gt;simulate&lt;/code&gt; function that allows you to run any protocol message or transaction against an alkane WASM, and this functions similar to what we are used to from Ethereum and refer to as view functions, but it is more comprehensive. You can simulate and compute fuel costs of a protocol message, mock any inputs desired as the balance sheet of assets you are spending into the transaction, get the list of expected alkanes that will be output from the transaction, see the list of storage updates as a result of the transaction, and of course, do all of it as if we are at an earlier block height than the current tip, if we want to see historical state.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;Well, it is true that people are excited already. We have projects deploying stablecoins, AMM systems, explorers, and of course we will have wallet support within OYL coming, so many of the pieces are already there or otherwise are staged to appear.&lt;/p&gt;

&lt;p&gt;Join us in the SANDSHREWサンド Discord where we discuss ALKANES and the greater ecosystem of metaprotocols we will come to know, as we enter the next chapter of Bitcoin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://discord.gg/wSrZtSrnrf" rel="noopener noreferrer"&gt;https://discord.gg/wSrZtSrnrf&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Software
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kungfuflex/alkanes-rs" rel="noopener noreferrer"&gt;https://github.com/kungfuflex/alkanes-rs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kungfuflex/alkanes" rel="noopener noreferrer"&gt;https://github.com/kungfuflex/alkanes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Announcements
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://x.com/judoflexchop" rel="noopener noreferrer"&gt;https://x.com/judoflexchop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Specifications
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kungfuflex/alkanes-rs/wiki" rel="noopener noreferrer"&gt;https://github.com/kungfuflex/alkanes-rs/wiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>blockchain</category>
      <category>bitcoin</category>
      <category>rust</category>
      <category>webassembly</category>
    </item>
  </channel>
</rss>
