<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>ApeWorX LTD</title>
        <link>https://paragraph.com/@apeworx</link>
        <description>The smart contract development tool for Pythonistas, Data Scientists, and Security Professionals</description>
        <lastBuildDate>Fri, 17 Apr 2026 00:22:59 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>ApeWorX LTD</title>
            <url>https://storage.googleapis.com/papyrus_images/50b1ba09d673cf2591c3cc78c86ebc08.jpg</url>
            <link>https://paragraph.com/@apeworx</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Introducing the Silverback Platform]]></title>
            <link>https://paragraph.com/@apeworx/introducing-the-silverback-platform</link>
            <guid>jJoujFdwYLISA3N4SdtH</guid>
            <pubDate>Wed, 12 Mar 2025 17:12:54 GMT</pubDate>
            <description><![CDATA[Almost 2 years ago, we introduced our vision for Silverback, a Platform for Web3 Bots, and today we are proud to announce that the Silverback Platform is finally live at silverback.apeworx.io! A lot has changed over the years, but one thing has remained constant: an obsession with giving you the most powerful tools to make building production bots as simple and easy as possible. Our Silverback SDK library is the fastest way today to build powerful Web3 automation in Python for use cases such ...]]></description>
            <content:encoded><![CDATA[<p>Almost 2 years ago, we introduced our vision for <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/apeworx.eth/WX2LApZC9qtDq4rop-sSwqARXNL0ZBzlCXXaAMJVjfc">Silverback, a Platform for Web3 Bots</a>, and today we are proud to announce that the Silverback Platform is finally live at <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://silverback.apeworx.io">silverback.apeworx.io</a>!</p><p>A lot has changed over the years, but one thing has remained constant: an obsession with giving you the most powerful tools to make building production bots as simple and easy as possible. Our Silverback SDK library is the fastest way today to build powerful Web3 automation in Python for use cases such as monitoring, trading, on-chain DevOps, indexing, crypto payments processing, and more. Anyone, right now, can build any bot to do anything, for free, using the Silverback SDK, just checkout the docs at <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.apeworx.io/silverback">https://docs.apeworx.io/silverback</a>. No login or payment required!</p><p>But now that its released and publicly available, you might be asking why Silverback is important? Why should I learn it and get involved? What will come next for the Silverback Platform if I build on it? Now that it is finally released, we can finally lay out our vision for what comes next!</p><div class="relative header-and-anchor"><h2 id="h-the-silverback-marketplace-and-building-for-ai">The Silverback Marketplace and Building for AI</h2></div><p>First off, now that the Silverback Platform is live it means that hobbyists who have already been building bots with the Silverback SDK can finally run them on our rock-solid hosted infrastructure, and delegate all the pains of cloud orchestration to be Someone Else's Problem<span data-name="tm" class="emoji" data-type="emoji">™</span>. For most of our existing userbase, this is probably something you have been waiting since we first mentioned the Platform: easy-to-build Python bots, that run autonomously on rock solid infrastructure managed by someone else, letting you sleep easy at night without having to worry about node outages, bot errors, and whatever other terrors await you off-chain. But there are many more people out there that wished they could run these types of bots but don't have the skills to write a few lines of simple Python! Silverback should exist for them too!</p><p>This is where the Platform comes in: we wanted to make it easy for operators to manage the operation of tens to hundreds of bots easily <em>without having to learn an ounce of Python</em>. The Silverback SDK ships out of the gate with the tools necessary to package and publish your bots into Docker images that <em>anyone</em> can run, allowing workflows where developers can easily publish (and monetize!) their automations for others to run.</p><hr><p>Imagine a hedge fund where traders can focus on complex filtering and trade execution, while data analysts can monitor existing strategies, all while partners have full control over the whole operation.</p><p>Imagine a talented Python developer who builds and refines popular actions such as token farming and arbitrage strategies for others to run on new protocols they are interested in (maybe even a hedge fund?)</p><p>Imagine building a complex FinTech application or integration with a larger traditional bank that simply leverages bots published by others for managing assets in popular DeFi protocols or monitoring for anomalies within their on-chain operations.</p><p>Imagine building a wealth of capabilities that a personalized LLM chat bot can use to evolve and execute your own bespoke market thesis, all without ever having to write a line of Python code yourself.</p><hr><p>This is what the Silverback Platform unlocks, a storefront for Web3 automation and capability. A way to extend yourself on-chain and compete within this global movement!</p><p>Sounds interesting, doesn't it?</p><div class="relative header-and-anchor"><h2 id="h-silverbackos-and-progressive-decentralization">silverbackOS and Progressive Decentralization</h2></div><p>For the more plugged-in Crypto-natives and just plain-old skeptics among us, that might sound great but the next question you might ask is...</p><p><em>"Do I have to trust the developers and operators of this hosted infrastructure with my entire on-chain life?"</em></p><p>What if there is an outage where we are hosting the Platform's infrastructure?</p><p>What if we go rogue and start doing something bad with your data?</p><p>What if we go out of business?</p><p>How do I really <em>trust</em> this?</p><hr><p>Well for this launch, we are the sole operators of the Platform, to make it even feasible in the short-term and unlock the capability for people to use it to host their bots. But that's not where we are going to stop.</p><p>One of the main promises of Crypto is unlocking massive coordination power, the ability to create much stronger and more resilient systems that can be relied on for years and decades to come. So today we are announcing our plans for the next stage of Silverback's evolution, transforming our centralized, hosted infrastructure into a fully-fledged <em>decentralized infrastructure network</em> capable of reliably and safely operating <strong>tens, maybe hundreds of millions of bots</strong> around the globe.</p><p>This will be a dramatic increase of the size and scope of Silverback's capabilities, and unlock countless use cases and even businesses where on-chain automation is the key ingredient to thrive. We are extremely excited to build this, and hope you are too. Stay tuned!</p><p><span data-name="gorilla" class="emoji" data-type="emoji">🦍</span> stronger together, with ApeWorX</p><hr><p><em>Need help? Join our Discord  where we can help you get set up and make the project of your dreams: </em><a target="_blank" rel="noopener noreferrer nofollow" class="dont-break-out" href="https://discord.com/invite/apeworx">https://discord.com/invite/apeworx</a></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
            <category>automation</category>
            <category>bots</category>
            <category>python</category>
            <category>ethereum</category>
            <category>defi</category>
            <category>trading</category>
            <enclosure url="https://storage.googleapis.com/papyrus_images/de6eb319d6cf0f9c516475b311863f4b.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Introducing Ape-Titanoboa, The New Standard In Testing]]></title>
            <link>https://paragraph.com/@apeworx/introducing-ape-titanoboa,-the-new-standard-in-testing</link>
            <guid>d521yylLlI9a4eWTRmFO</guid>
            <pubDate>Fri, 31 Jan 2025 17:28:41 GMT</pubDate>
            <description><![CDATA[We're proud to announce that Ape now fully supports Titanoboa via the ape-titanoboa plugin! With it you can speed up your workflow, lower dev time and do hybrid testing, utilizing the built-in testing suite in Ape alongside Titanoboa to find bugs up to 2x quicker! Let's go through everything:Understanding Titanoboa: The New Standard for Speedy Testing in ApeOne of the biggest struggles of smart contract development is balancing proper testing with speed. You can have the most solid contract c...]]></description>
            <content:encoded><![CDATA[<p>We're proud to announce that Ape now fully supports Titanoboa via the ape-titanoboa plugin! With it you can speed up your workflow, lower dev time and do hybrid testing, utilizing the built-in testing suite in Ape alongside Titanoboa to find bugs up to 2x quicker!</p><p>Let's go through everything:</p><div class="relative header-and-anchor"><h2 id="h-understanding-titanoboa-the-new-standard-for-speedy-testing-in-ape">Understanding<strong> </strong>Titanoboa: The New Standard for Speedy Testing in Ape</h2></div><p>One of the biggest struggles of smart contract development is balancing proper testing with speed. You can have the most solid contract code in the world but testing it will be nothing but a headache if you're forced to test it in a language lacking proper testing support. Ape framework solves this by allowing you to write full integration tests with the structured flexibility of python and pytest behind it, but for many tests doing a full provider construction, transaction, block mining, and tear-down takes too much time and can really add up in the full test suite.</p><p>Enter Titanoboa, a Vyper interpreter that Ape uses to streamline the testing of smart contracts by eliminating the need for transactions, signing processes, and reliance on provider applications.</p><p>Titanoboa simplifies this by running EVM opcodes directly, significantly reducing the overhead and drastically speeding up testing.</p><div class="relative header-and-anchor"><h2 id="h-the-traditional-approach-to-testing-smart-contracts"><strong>The Traditional Approach to Testing Smart Contracts</strong></h2></div><p>When you compile a smart contract, it generates Ethereum Virtual Machine (EVM) opcodes. These opcodes are the fundamental instructions that dictate how the contract operates within the blockchain environment. Typically, users interact with blockchains through transactions that include a "data" field, specifying which code to execute from the smart contract. This method is effective but introduces significant overhead  during the testing phase. Most traditional testing tools require devs to manage private keys, sign transactions, and run developer nodes (Hardhat, Geth, Anvil, etc), slowing down the development and testing processes massively.</p><p>Ape-titanoboa is different. It runs EVM opcodes rather than relying on transactions, signing, or any of the above, lowering overhead massively. </p><p>By cutting out the transaction burden, Titanoboa allows for much faster execution of the smart contract logic, drastically speeding up the processes and cutting out a massive amount of time needed in the testing process.</p><p>Now you still can (and should!) do slower, full integration tests, but you are no longer forced to.</p><div class="relative header-and-anchor"><h2 id="h-pros-and-cons-of-using-titanoboa"><strong>Pros and Cons of Using Titanoboa</strong></h2></div><p>Here's an (almost) complete rundown of the pros/cons of Titanoboa:</p><div class="relative header-and-anchor"><h2 id="h-pros"><strong><u>Pros:</u></strong></h2></div><ul><li><p><strong>Faster Testing</strong>: The primary benefit is speed; developers can test their code more quickly, leading to more iterations and improvements.</p></li><li><p><strong>Reduced Overhead</strong>: The elimination of transaction-related complexities makes it easier to focus on specific logic within smart contracts.</p></li><li><p><strong>Enhanced Testing</strong>: Titanoboa makes it easier to test your smart contract's specific logic and target specific parts too ensure they run the way you want them to.</p></li></ul><ul><li><p><strong>Simplicity</strong>: Developers can focus on testing specific functionalities without getting bogged down by transaction mechanics.</p></li></ul><ul><li><p><strong>Flexibility</strong>: Titanoboa provides tools to manipulate execution blocks and timestamps, enabling more dynamic testing scenarios.</p></li></ul><div class="relative header-and-anchor"><h2 id="h-cons"><strong><u>Cons:</u></strong></h2></div><ul><li><p><strong>Realism Issues</strong>: Because it cuts out some transactions, some aspects may not reflect real-world scenarios accurately.</p></li><li><p><strong>Potential Bugs</strong>: Running code in a simplified environment may expose developers to bugs that wouldn’t appear in a fully integrated system.</p></li><li><p><strong>Limited Integration Testing</strong>: While unit tests can be executed quickly, integration tests are still necessary to ensure you're fully covered.</p></li></ul><p>While it may not fully replace regular testing completely (especially for integration testing) Boa is basically the new testing standard and an incredibly powerful tool to streamline development and for actually making your project a reality.</p><hr><p><strong>Integrating Titanoboa with Ape Framework</strong></p><p>There's three key things to understand about this integration:</p><ol><li><p><strong>TestProviderAPI</strong>: This API includes essential methods like set_balance(), pending_timestamp (which lets you manipulate time) and mine() which controls blockchain changes during testing.</p></li><li><p><strong>The Titanoboa Plugin itself</strong>: The new plugin processes transactions directly by executing EVM opcodes and returning a computation-wrapper akin to receipts (which can even implement the ReceiptAPI).</p></li></ol><p>Using these alongside your regular Ape tools will let you try out ape-titanoboa, letting you cut out the cruft and test what you want to test as fast as possible.</p><hr><p>To show just how much of an improvement ape-titanoboa is, lets test it with our tool ApePay using both ape-foundry and ape-titanoboa:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/c9217bf857df6d8eb824b4353552907e.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAANCAIAAABHKvtLAAAACXBIWXMAAAsTAAALEwEAmpwYAAABcklEQVR4nK2SMUsCYRjHn0VaHAqabTENHBqu5Y4EBeEOg4KGAz9ANdUQpNuRQQ19iKKl+gg1BAoOZUuKDeq51J3Ie9whvC+PWcqFeopB0909/If35YHnN/x/QBnrEJLN5jhuQ1EU2+8ByliXUo7jACAUWvm7Hfa/+j4AOoTM/oPhEBG7lFLGKGOISAyjQ4jrOIBa7Z0X4qK0JUrp7Z3dw6NjWc7wQjwcjlxd3zy/vBaKJXdxAJVqjRfigYUgAAQWgolkanR9dQ0Azi8ufQDYto3YM00TESljH58aMQzTNCljqtqqN5qu45ScP81LkqRpGk5njHTGa8n9n+9oJAoA5XJ53PNgsvN4+h+LEHFikWVZ8xYRD3EAb5VqIpmS5YwopWU5c5LN7e0fiFKaFzZv7+59KLneaM4sAoBEMhWLrS8uLQOAopwViqWHxyd3cQDEMHS9bVkWYg8Rdb09sQgRVbXlJfOaom2PCpiaM3v3nL5czS/oPA7XbMMhIQAAAABJRU5ErkJggg==" nextheight="449" nextwidth="1086" class="image-node embed"><figcaption htmlattributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>As you can see, its no contest. In our other tests it reached up to +2x speed increases (and we aim to bump that up even more with the upcoming updates).</p><hr><p>People say that speed is a luxury or a frill, but in reality it's a necessity in the world of crypto development. </p><p>Tools like Titanoboa allow you to have quicker testing cycles, focus on actually building vs waiting around, and let you avoid getting bogged down by unintuitive processes like writing tests in Solidity. One of our goals this year is to become one of the fastest frameworks, not only the most customizable one.</p><hr><p>If you want to experience the newer, faster, Ape+Titanoboa, download it here: <a target="_blank" rel="noopener noreferrer nofollow" class="dont-break-out" href="https://github.com/ApeWorX/ape-titanoboa">https://github.com/ApeWorX/ape-titanoboa</a></p><hr><p>Need help? Join our Discord  where we can help you get set up and make the project of your dreams: <a target="_blank" rel="noopener noreferrer nofollow" class="dont-break-out" href="https://discord.com/invite/apeworx">https://discord.com/invite/apeworx</a></p><hr><p><span data-name="gorilla" class="emoji" data-type="emoji">🦍</span><span data-name="handshake" class="emoji" data-type="emoji">🤝</span><span data-name="snake" class="emoji" data-type="emoji">🐍</span></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
            <category>crypto</category>
            <category>ape</category>
            <category>vyper</category>
            <category>titanoboa</category>
            <category>dev</category>
            <category>cryptocurrency</category>
            <category>python</category>
            <category>ape-titanoboa</category>
            <enclosure url="https://storage.googleapis.com/papyrus_images/75aa79a92dd37e9000166427d793b248.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[How to create a Silverback Yield Monitor Bot for ERC-4626 Vaults]]></title>
            <link>https://paragraph.com/@apeworx/building-and-running-a-silverback-yield-bot-with-erc4626-vault</link>
            <guid>LimuV0LA6OBlLPftA6ap</guid>
            <pubDate>Tue, 15 Oct 2024 17:33:05 GMT</pubDate>
            <description><![CDATA[Unlock the true yield of ERC-4626 vaults with a Yield Monitor Bot! Using the Silverback framework, this bot listens to Ethereum blocks, fetches real-time vault share prices, and verifies the actual yield of tokenized vaults. No more relying on posted yields—get accurate insights with each block mined. Learn how to set it up, track multiple vaults, automate DeFi strategies, and more. Ready to level up your DeFi game? Full guide inside!]]></description>
            <content:encoded><![CDATA[<p>One of the most groundbreaking changes in the Ethereum ecosystem was the creation of <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/">ERC-4626</a>, a method for tokenizing yield earning vaults.</p><p>In this guide, we’ll walk you through the steps to clone an ERC4626 bot project, configure your environment, and run a bot built using the Ape Framework and Silverback. Because of how the yield is abstracted into a token it becomes harder to figure out how much true yield the protocol is generating vs what's stated on the protocol or issuers site. This means that unless you’re calculating the returns you’re getting from an ERC-4626 token every day then you have to trust that the posted yield is what you’re actually getting. By the end of this tutorial, you’ll be able to observe real-time Ethereum block data and vault share prices right from your terminal.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/1855cd4a8021bfebaef54e2d351e9b7a.jpg" blurdataurl="data:image/png;base64,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" nextheight="356" nextwidth="475" class="image-node embed"><figcaption htmlattributes="[object Object]" class="hide-figcaption"></figcaption></figure><p><br>But this is crypto. Trust is bullshit. Here’s how you can build a bot to verify the yield for you.</p><div class="relative header-and-anchor"><h3 id="h-why-silverback">Why Silverback?</h3></div><p>Silverback is a framework designed to help you create bots that interact with the blockchain. It simplifies tasks like:</p><ul><li><p>Listening for events (e.g., new blocks, transactions)</p></li><li><p>Fetching live data (e.g., token prices, vault share values)</p></li><li><p>Automating DeFi strategies( Advance )</p></li></ul><p>You can easily run your bots with a minimal amount of code while taking advantage of Silverback's <strong>modular design</strong> and <strong>asynchronous task management</strong>. Let’s dive in!</p><div class="relative header-and-anchor"><h3 id="h-what-does-the-bot-do">What Does the Bot Do?</h3></div><p>The bot you're setting up is a <strong>price checker</strong> for an ERC4626-compliant vault. It listens for new blocks on the Ethereum blockchain and retrieves the <strong>current share price</strong> from a vault every time a block is mined. Specifically, the bot does the following:</p><ol><li><p><strong>Monitors New Ethereum Blocks</strong>: It uses the Silverback framework to listen for block events in real-time on the Ethereum mainnet.</p></li><li><p><strong>Fetches Vault Share Price</strong>: Each time a new block is created, the bot queries the share price of the ERC4626 vault. The share price represents the value of vault shares, which fluctuate as assets are deposited, withdrawn, or accrue yield within the vault.</p></li><li><p><strong>Logs the Results</strong>: The bot logs the block number, block hash, and the updated share price, allowing users to see how the vault's value evolves with each block.</p></li></ol><p>In simple terms, this bot provides live data on the value of an ERC4626 vault, giving you insights into how the vault performs in real-time as transactions occur on the Ethereum network.</p><p>The code for this project is available <a target="_new" rel="noopener" class="dont-break-out" href="https://github.com/ApeAcademy/erc-4626/tree/demo">here</a></p><div class="relative header-and-anchor"><h2 id="h-step-by-step-guide">Step-by-Step Guide</h2></div><div class="relative header-and-anchor"><h3 id="h-1-clone-the-project">1. Clone the Project</h3></div><p>First, let’s clone the repository from GitHub make sure your copy the <strong>demo branch</strong></p><pre data-type="codeBlock" language="bash"><code>git <span class="hljs-built_in">clone</span> https://github.com/ApeAcademy/erc-4626.git
git checkout remotes/origin/demo
<span class="hljs-built_in">cd</span> erc-4626</code></pre><p>This project contains all the code necessary to run a bot that interacts with ERC4626-compliant vaults.</p><div class="relative header-and-anchor"><h3 id="h-2-set-up-environment-variables">2. Set Up Environment Variables</h3></div><p>In this tutorial I <code>export</code> the variable in my cli session so I don't have to create an <code>.env</code> file. Here is how to to do that:</p><pre data-type="codeBlock" language="bash"><code><span class="hljs-built_in">export</span> WEB3_ALCHEMY_PROJECT_ID=your-alchemy-id
<span class="hljs-built_in">export</span> ERC4626_VAULT_ADDRESS=your-vault-address

<span class="hljs-built_in">echo</span> <span class="hljs-variable">$WEB3_ALCHEMY_PROJECT_ID</span>
<span class="hljs-built_in">echo</span> <span class="hljs-variable">$ERC4626_VAULT_ADDRESS</span></code></pre><p>Replace <code>your-alchemy-id</code> with your actual API key from Alchemy, and replace <code>your-vault-address</code> with the address of the ERC4626 vault you want to interact with. I used a <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0x583019ff0f430721ada9cfb4fac8f06ca104d0b4"><s>yearn vault</s></a> <code>ERC4626_VAULT_ADDRESS=0x583019fF0f430721aDa9cfb4fac8F06cA104d0B4</code></p><div class="relative header-and-anchor"><h3 id="h-3-install-dependencies">3. Install Dependencies</h3></div><p>Next, we need to install the required Python packages and Ape Framework plugins. Run the following command:</p><pre data-type="codeBlock" language="bash"><code>pip install -r requirements.txt
ape plugins install . -U</code></pre><p>This will install Silverback, Ape Framework, and any other dependencies required to run the bot.</p><div class="relative header-and-anchor"><h3 id="h-4-configure-ape-framework">4. Configure Ape Framework</h3></div><p>Ensure your <code>ape-config.yaml</code> file is configured to use Alchemy as the default provider for Ethereum mainnet. If you want to learn more how to configure your <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.apeworx.io/ape/stable/userguides/config.html">ape-config.yaml</a></p><p>If you cloned the project you ape-config.yaml should look like this:</p><pre data-type="codeBlock" language="yaml"><code><span class="hljs-attr">name:</span> <span class="hljs-string">ERC4626</span>
<span class="hljs-attr">plugins:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">vyper</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">alchemy</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">etherscan</span>

<span class="hljs-attr">ethereum:</span>
  <span class="hljs-attr">default_network:</span> <span class="hljs-string">mainnet</span>
  <span class="hljs-attr">mainnet:</span>
    <span class="hljs-attr">default_provider:</span> <span class="hljs-string">alchemy</span></code></pre><div class="relative header-and-anchor"><h3 id="h-5-running-the-bot">5. Running the Bot</h3></div><p>With one simple command you can run the project with:</p><p><code>silverback run bots.silverback_yield:bot</code></p><p>The bot will start monitoring Ethereum blocks and printing out the share price of the ERC4626 vault every time a new block is mined. Here's a sample output you can expect:</p><pre data-type="codeBlock"><code>Price Event: <span class="hljs-number">0</span><span class="hljs-number">.9547177472995926</span>
SUCCESS: update_shareprice[block_number<span class="hljs-operator">=</span><span class="hljs-number">20915791</span>,block_hash<span class="hljs-operator">=</span><span class="hljs-number">0xb0b2215bce3801b0412e39b75eb73ef2f7ad8d9618c32d1460086c1cb41ed9eb</span>] <span class="hljs-operator">-</span> <span class="hljs-number">0</span>.340s (<span class="hljs-number">2.6</span><span class="hljs-operator">%</span>)
Price Event: <span class="hljs-number">0</span><span class="hljs-number">.9547177355383596</span>
SUCCESS: update_shareprice[block_number<span class="hljs-operator">=</span><span class="hljs-number">20915792</span>,block_hash<span class="hljs-operator">=</span><span class="hljs-number">0x27c1c49273640ac02ea87ed934fa7dd367aea4803005373b1b13d0c34201600a</span>] <span class="hljs-operator">-</span> <span class="hljs-number">0</span>.360s (<span class="hljs-number">2.8</span><span class="hljs-operator">%</span>)
</code></pre><div class="relative header-and-anchor"><h3 id="h-silverback-bot-code-simple-and-effective">Silverback Bot code: Simple and Effective</h3></div><p>Below is the core code for our Silverback bot that monitors an ERC4626 vault:</p><pre data-type="codeBlock" language="python"><code><span class="hljs-keyword">import</span> os

<span class="hljs-keyword">from</span> ape <span class="hljs-keyword">import</span> Contract, chain, networks
<span class="hljs-keyword">from</span> silverback <span class="hljs-keyword">import</span> SilverbackBot

bot = SilverbackBot

<span class="hljs-keyword">with</span> networks.ethereum.mainnet.use_provider(<span class="hljs-string">"alchemy"</span>):  <span class="hljs-comment"># or "infura"</span>
    vault = Contract(os.environ.get(<span class="hljs-string">"ERC4626_VAULT_ADDRESS"</span>))

one_share = <span class="hljs-number">10</span> ** vault.decimals()


<span class="hljs-meta">@bot.on_(<span class="hljs-params">chain.blocks</span>)</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">update_shareprice</span>(<span class="hljs-params">_</span>):
    <span class="hljs-string">"""
    Convert shares to a set price unit.
    """</span>
    price = vault.convertToShares(one_share) / one_share
    <span class="hljs-comment"># Total number of shares in the vault divide by </span>
    <span class="hljs-comment"># the current unit price of a share  = gwei </span>
    <span class="hljs-built_in">print</span>(<span class="hljs-string">f"Price Event: <span class="hljs-subst">{price}</span>"</span>)</code></pre><ul><li><p><strong>Network Connection</strong>: The bot connects to the Ethereum mainnet using either <strong>Alchemy</strong> or <strong>Infura</strong> as the provider.</p></li><li><p><strong>Vault Contract</strong>: The <code>Contract</code> object connects to the specified ERC4626 vault via the contract address defined in your environment variables.</p></li><li><p><strong>Price Update</strong>: The bot listens for new blocks (<code>@bot.on_(chain.blocks)</code>) and triggers the <code>update_shareprice</code> function every time a new block is mined. It retrieves the vault’s current share price by calling the <code>convertToShares</code> method on the vault contract and logs the price event.</p></li><li><p><strong>Cluster</strong>: In the cluster, if you return data from one of the handlers, the cluster will collect that data for later review</p></li></ul><div class="relative header-and-anchor"><h3 id="h-6-troubleshooting">6. Troubleshooting</h3></div><ul><li><p><strong>Missing </strong><code>.env</code><strong> file</strong>: Ensure your <code>.env</code> file is in the root of your project directory and formatted correctly.</p></li><li><p><strong>Provider Errors</strong>: Double-check that your <code>WEB3_ALCHEMY_PROJECT_ID</code> is correct and that you’ve set the correct default network in <code>ape-config.yaml</code>.</p></li><li><p><strong>FileNotFoundError</strong>: If you get an error related to missing directories, verify that your <code>bots/</code> folder is in the root of the project.</p></li></ul><div class="relative header-and-anchor"><h3 id="h-next-steps"><strong>Next Steps</strong></h3></div><p>Now that you’ve successfully set up and run your first Silverback bot, consider expanding its functionality:</p><ul><li><p><strong>Track Multiple Vaults</strong>: Extend the bot to monitor multiple ERC4626 vaults at the same time.</p></li><li><p><strong>Automate Transactions</strong>: Add logic to trigger a transaction when certain conditions are met, such as depositing or withdrawing assets based on share price thresholds.</p></li><li><p><strong>Notify Users</strong>: Integrate email or messaging alerts when certain events occur, such as a significant change in vault value.</p></li></ul><p>With Silverback, you’re not just limited to monitoring prices—automating DeFi strategies is just as easy!</p><div class="relative header-and-anchor"><h3 id="h-advance-yield-example"><strong>Advance Yield Example</strong></h3></div><p>Check out the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ApeAcademy/erc-4626/"><strong>main branch </strong></a>of this demo, it has advance yield calculations for a year's worth of time. It uses a local database via SQ-lite to store the data. The data can accessed by a bot on a Silverback cluster to perform strategies such as liquidate, buy, sell, and so much more. </p><p>One of the most groundbreaking changes in the Ethereum ecosystem was the creation of ERC-4626, a method for tokenizing yield earning vaults. </p><ul><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/"><u>ERC-4626 Standard</u></a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://academy.apeworx.io/articles/erc-4626-tokenized-vault-standard"><u>ERC-4626 Ape Explanation</u></a><u> </u></p></li></ul><p>Yield is abstracted into a token it becomes harder to figure out how much true value the protocol is generating vs what's stated on the protocol or issuers site. This means that unless you’re calculating the returns you’re getting from an ERC-4626 token every day then you have to trust that the posted yield is what you’re actually getting.</p><div class="relative header-and-anchor"><h2 id="h-lets-stay-connected">Let's stay connected! </h2></div><p>Subscribe so you can see the next tutorials where we teach you everything from how to make an automated trading bot to building a bot that scans the chain in real time to one that makes a hotdog powered stablecoin.<br><br>Also if you want the latest on Silverback and to see our experiments, join the hidden Telegram chat where we post our latest tools and tips on botcrafting so you can build your robot army:<br><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://t.me/ApeSilverback">Telegram Silverback</a><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://t.me/ApeSilverback￼￼If"><br><br></a>If you want more Apey goodness, check out our Discord where we go deep into the Ape Framework, crypto engineering, and how you can customize your setup to let you work faster than you could ever have imagined.<br><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/invite/apeworx">ApeWorX Discord</a></p><p></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
            <author>apeworx@newsletter.paragraph.com (Ninjagod)</author>
            <category>erc-4626</category>
            <category>silverback</category>
            <category>apeworx</category>
            <category>yield</category>
            <category>ethereum</category>
            <category>vaults</category>
            <category>defi</category>
            <category>automation</category>
            <category>ape</category>
            <category>blockchain</category>
            <category>tokenization</category>
            <category>crypto</category>
            <enclosure url="https://storage.googleapis.com/papyrus_images/d6f55e507d0ed5b0d84af11acd0609e8.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Ape Scream]]></title>
            <link>https://paragraph.com/@apeworx/ape-scream</link>
            <guid>J6AQbexPkQSM5wUWFyzz</guid>
            <pubDate>Wed, 26 Jun 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Ape ScreamProject OverviewAt ApeWorX we're used to creating bots and plugins to serve a useful purpose and make people's lives easier. So as a break f...]]></description>
            <content:encoded><![CDATA[<div class="relative header-and-anchor"><h1 id="h-ape-scream">Ape Scream</h1></div><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/53297370589db8b28868a99398e87790.webp" blurdataurl="data:image/png;base64,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" nextheight="1024" nextwidth="1024" class="image-node embed"><figcaption htmlattributes="[object Object]" class="hide-figcaption"></figcaption></figure><div class="relative header-and-anchor"><h3 id="h-project-overview">Project Overview</h3></div><p>At ApeWorX we're used to creating bots and plugins to serve a useful purpose and make people's lives easier.</p><p>So as a break from all that we thought "What's the silliest Silverback bot we could make?" and came up with the idea of making a bot that screams into the void every time you make a transaction.</p><p>My name is Chris, and in this tutorial I'm going to show you how you combine Warpcast Frames, Generative AI, Vyper and Silverback to make a unique picture based on specific conditions on the blockchain and post it to Farcaster</p><div data-type="callout" type="info"><div class="callout-base callout-info" data-node-view-wrapper="" style="white-space:normal"><img src="https://paragraph.xyz/editor/callout/information-icon.png" class="callout-button"><div class="callout-content"><div><p>To follow along with this project, clone: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/Ninjagod1251/silverbackEcho">https://github.com/ApeAcademy/SilverbackEcho</a></p></div></div></div></div><div class="relative header-and-anchor"><h3 id="h-project-inspiration">Project Inspiration</h3></div><p>The inspiration for this project came from a Telegram channel called<strong> </strong><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/DaoScream"><strong>Bear Market Screaming Therapy</strong></a>, dedicated to audio messages of people screaming. I wanted to automate a similar concept using Silverback and Farcaster. </p><p>Perfect. Now let's put it on chain (or at least a testnet).</p><div class="relative header-and-anchor"><h3 id="h-project-implementation">Project Implementation</h3></div><p>This project involves integrating a simple Vyper contract called <code>echo.vy</code> with a Silverback bot connected to Warpcast and a Generative AI service to post a unique picture by watching for an Event to emit a <code>Received</code> message. </p><p>Basically on-chain void-screaming</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/9f454dac7123599e37845abdcd88d656.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAIAAAAUMWhjAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEQElEQVR4nK1VX0xbVRi/Mb4ZE59M3KsxJiQ+LDEakyU+GLPonqaiYKiGQAMMt4SSMVhMh2P8mSUQgSG2GaXSAeu4UNmlA/E6FlpaoZDSltLM216y3trWWziTU3vAAxzTeyZjQEgh/h5u7rk35/ud7/t9v+8whJDaWm1rcz0hxHyr7we93mg0suxQj8nU2tbe1t7RYzL1ms0IIZIdMMa7n0xV5XlGwWdnT+tavjt16t3cT/PyPy8oKlafv3ChsLCwqLi47lp9Op0+PG5Uki5WXdI1t1RVVff33yaEiKKIEGLOfPA+JcjPPZPe+Mfr8y0sBha8fghT5Cj4O5UShJAkRUOCEJWiGGMIYSYDQsiXqrw3T+ZsrK+73W6WHeJ5nuM4i8UiCKEtQhBCWAE5FpjdO0OCwHGcSwHP87FY7HhBnyEgyhkRypS4r69vdNRms41ZR2z3Jx9wHDdgYQfZIYuFDQaDimibxyGgwBhHIpF4PBESQkI4HFgKyrL8KCKFRVEQQsnkCiHbezZvHRSR1nOnME8JsgR+dv+e5QEZ0H+RSOQOe2dychJjvLW5hfEmQmjKPm0b+/lRRBqf4Ietdx9M2WlvAAAghBO/8CxrFUURwjUAADWKKC5z3OiU3TE+wStJ/0cwP7dQVFRad7WJfiWEbGA8bL3b2tY57/EYTeaGRp3R9CMliMcTAIBec19Do87jWQAAxGIxShAWlw3dPYbuno5OfVhcfkIgimHPXHCg12Y2jiwFBEK2IUwpXby5J32EED0+7XFCCH2HEO7vZrpkbhr01Gg6XVNefr5ara7QaNRq9Ucff1Kg+qKktOy6rsVoMuta2rr03TOzcyxr3R1iv+w7qiSTK8nkCvP2WycpQdf3Nxobm6prLtvtDloKCgAeI7ROD34kxz3JgDr5esM3EKYkKQoAiMcThJBkciX7AUeBMf5D8aZSsXWMcTqdfupkr88vCCEIodPlQgjNzM5RJrwL5FD8tbZmuGkihPj9gXg8kUyuOBzOTAYAgP0uPdBER5nV27RHGKfTzjDMC88xBoOhsLBIo6m8Ult7rvyrApXqXHl5haayta29//Zgl76799aAIvJPWdIA8Dgjcs7rr1KRm+qvai5eKiktG2TZkCD4/X6vzxdYCjz8XZCkqNfnD4tiOp1eXV0l2QGh9cx9IMvy8wyTe/ZDCFPBYFAUReq1481npPQFVVipktJFFF7/YjD4EELocv2GEHI4nJJyb+wR+RBiRWSjIvIiFdnpcjE78u6eX8fLAONN2i87roYQMok/Eydeeen0e++w7FB1Tc23uuaOjg6tVluh0Wi12rpr9UaTmeNsFnZ4hLPNezz3xiey5KMmZd7IeY2K/PXlqpLSsgKV6kZnJ8//yrJDw1brvbGxKbsjsLTE35+cmZ2TZTksilkSIIQyGUw7pxmGOfHyi7Isu93umdnZ/+Wm3MG/PHnZJMaHRkoAAAAASUVORK5CYII=" nextheight="557" nextwidth="754" class="image-node embed"><figcaption htmlattributes="[object Object]" class="hide-figcaption"></figcaption></figure><div class="relative header-and-anchor"><h3 id="h-silverback-hollabackpy-breakdown">Silverback Hollaback.py breakdown:</h3></div><p><code>Hollaback.py</code> is the Silverback bot itself. This is shinning star of the whole project. If you take away anything from this, it is this right here. This tool can be expanded on and to form so many projects integrating the off-chain and on-chain worlds. So let's breakdown the code:</p><pre data-type="codeBlock" language="python"><code><span class="hljs-keyword">from</span> silverback <span class="hljs-keyword">import</span> SilverbackApp

<span class="hljs-comment"># Initialize the Silverback app first</span>
app = SilverbackApp()</code></pre><p>We want to trigger our logic based off of the event we want to watch. To do that, we add the a decorator <code>@app.on_(my_contract.Received)</code> to define what we are going to watch for from on-chain. </p><div data-type="callout" type="info"><div class="callout-base callout-info" data-node-view-wrapper="" style="white-space:normal"><img src="https://paragraph.xyz/editor/callout/information-icon.png" class="callout-button"><div class="callout-content"><div><p>For more help on creating an application, see the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.apeworx.io/silverback/stable/userguides/development.html#creating-an-application">Silverback Docs</a></p></div></div></div></div><p>Initializing the app creates a network connection using the Ape configuration of your local project, making it easy to add a Silverback bot to your project in order to perform automation of any necessary on-chain interactions. We will keep this app in a separate folder called <code>bots/</code>.</p><p>When the event <code>Received</code> is emitted, we are going to cast a message "AH" with the number of H's    based on an equation we made <code>(text="A" + "H" * floor(log2(log.amount)))</code>, if the amount of wei in the log is <code>&gt;= 0.001 ether</code>. We will cast the message using <code>client.post_cast(text=scream)</code>.</p><p>Here is the simplified code:</p><pre data-type="codeBlock" language="python"><code><span class="hljs-keyword">from</span> ape <span class="hljs-keyword">import</span> convert
<span class="hljs-keyword">from</span> ape_farcaster <span class="hljs-keyword">import</span> Warpcast
<span class="hljs-keyword">from</span> silverback <span class="hljs-keyword">import</span> SilverbackApp

app = SilverbackApp()
client = Warpcast(app.signer)


<span class="hljs-meta">@app.on_(<span class="hljs-params">my_contract.Received</span>) </span><span class="hljs-comment"># defined what event to watch</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">payment_received</span>(<span class="hljs-params">log</span>): <span class="hljs-comment"># execute this on every log</span>
   client.post_cast(text=<span class="hljs-string">"A"</span> + <span class="hljs-string">"H"</span> * floor(log2(log.amount))) <span class="hljs-comment">#A + xH do the math, and then using the post_cast(text=AHHHHH)</span></code></pre><p>In order to make this project more appealing and creative. We are going to add some creative ways to generate some fun. </p><div class="relative header-and-anchor"><h3 id="h-generating-ai-images">Generating AI images</h3></div><p><code> client.post_cast(text="A" + "H" * floor(log2(log.amount)))</code> is the single line of code to publish a message to Farcaster. Casting an image requires <code>client.post_cast(embeds=&lt;direct_url_link_to_image&gt;)</code>. So the game plan and puesdo code goes as follows: </p><pre data-type="codeBlock" language="python"><code>app.on_(my_contract.Received)
<span class="hljs-keyword">def</span> <span class="hljs-title function_">payment_received</span>(<span class="hljs-params">log</span>):
   client.post_cast(embeds=&lt;direct_url_link_to_image&gt;)
<span class="hljs-string">"""
log provides 2 values address of sender and amount of weth sent.
1. create prompt
2. create image(prompt)
3. upload image to Pinata
4. Cast message with address of sender and image 
"""</span>

<span class="hljs-keyword">def</span> <span class="hljs-title function_">create_prompt</span>(<span class="hljs-params">number_adj: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">str</span>:
<span class="hljs-string">"""
1. This method creates a prompt based off of the address sending eth.
"""</span>

<span class="hljs-keyword">def</span> <span class="hljs-title function_">createImage</span>(<span class="hljs-params">prompt</span>) -&gt; <span class="hljs-built_in">str</span>:
<span class="hljs-string">"""
 2. Creates an image based off the prompt.
"""</span>

<span class="hljs-keyword">def</span> <span class="hljs-title function_">uploadToPinata</span>(<span class="hljs-params">image</span>):
<span class="hljs-string">"""
3 . Uploads image to pinata and returns an ipfs hash.
"""</span></code></pre><div class="relative header-and-anchor"><h3 id="h-creating-the-prompt">Creating the prompt</h3></div><p>Creating the prompt uses a library called <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://pypi.org/project/wonderwords/">wonderwords</a> this helps us generate adjectives to fill in the prompt <code>" An ape {adjective_string} ape that is screaming AHHHHH"</code>.</p><div class="relative header-and-anchor"><h3 id="h-create-an-image">Create an Image</h3></div><p>Using the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://Stability.ai">Stability.ai</a> documentation on how to create an image via <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://platform.stability.ai/docs/api-reference#tag/Generate/paths/~1v2beta~1stable-image~1generate~1sd3/post">post request</a> we imported our own API key and the prompt and return the file name of the generated image. </p><p><strong>Note</strong> there is a chance that the prompt has a word that is not approved so that is why we have the prompt in a 10 try for loop. </p><div class="relative header-and-anchor"><h3 id="h-upload-image-to-pinata">Upload Image to Pinata</h3></div><p>Once the image is created, it needs to be uploaded to a place where a direct link to the image can be referenced. We decided to use <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://Pinata.cloud">Pinata.cloud</a> to host it since it is easy to use. I used a combination of their <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.pinata.cloud/api-reference/endpoint/pin-file-to-ipfs">docs </a>and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://stackoverflow.com/questions/69086493/pinning-directory-through-pinata-api-with-python">stackoverflow</a> to find a way to pin a file to ipfs.</p><p>At this point, you understand how the whole hollaback script works and you just need to let the magic fly!</p><div class="relative header-and-anchor"><h3 id="h-running-the-project">Running the Project</h3></div><p>To run the project: first deploy the Vyper contract using this <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://academy.apeworx.io/tutorials/deploying-contracts">tutorial to deploy contracts</a>. Since we only need to deploy this contract once, I just use <code>ape console --network :sepolia</code> and then record the contract address emitted by the script. </p><p>Then, run the Silverback App via <code>silverback run bots.hollaback:app --network :sepolia --account &lt;your Farcaster address&gt;</code>. Finally, to trigger the interaction, use <code>ape run holla --network :sepolia --account &lt;your payment account&gt;</code> in a separate terminal. The Silverback App will monitor the contract event emitted when you run the <code>holla</code> script, which will trigger the post as long as the conditions are met.</p><div class="relative header-and-anchor"><h3 id="h-conclusion">Conclusion</h3></div><p>And ta-da! You now have a bot that you can use to vent your frustration and tokenize any and all existential crisis.</p><p>If you want to learn more about Silverback feel free to check out our <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.gg/apeworx">Discord</a>, and if if you liked this tutorial you'll love our tutorial on how to <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://paragraph.xyz/@apeworx/how-to-build-a-crypto-project-like-an-aerospace-engineer">build a defi app like an aerospace engineer</a>.</p><p></p><p></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (Ninjagod)</author>
            <category>silverback</category>
            <category>bot</category>
            <category>generative-ai</category>
            <category>farcaster</category>
            <enclosure url="https://storage.googleapis.com/papyrus_images/fca80fc4b8e203e23bb69002d6535bab.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Package Management Wars]]></title>
            <link>https://paragraph.com/@apeworx/package-management-wars</link>
            <guid>Ukbz5EFLpiD4nbnOEAoA</guid>
            <pubDate>Tue, 11 Jun 2024 01:01:01 GMT</pubDate>
            <description><![CDATA[Over the past 7 years, I have been involved in various efforts to try and combat the widespread issues with managing code for Ethereum applications. ...]]></description>
            <content:encoded><![CDATA[<p>Over the past 7 years, I have been involved in various efforts to try and combat the widespread issues with managing code for Ethereum applications. Most notably, I have contributed to the development and adoption of the EthPM v3 standard, first with Brownie and then over the past 3 years integrating it as a core part of Ape.</p><p>I know as well as anyone that if you ask any type of seasoned developer, whether they are protocol developers that need to integrate with other applications, security researchers trying to understand the impact of potential bugs, or really just anyone trying to get an ABI to interact with a contract from a web page or python script, you will hear a litany of issues related to figuring out what the source code is and how to compile it and publish it correctly. It is probably the single biggest issue holding us back from truly making accelerated progress as an ecosystem, and is probably Ethereum's worst original sin that there was not a consistent way to share this information from within the protocol.</p><p>I probably can't sum up the current state of affairs any better than banteg has:</p><div data-type="twitter" tweetid="1799189828619408000"> 
  <div class="twitter-embed embed">
    <div class="twitter-header">
        <div style="display:flex">
          <a target="_blank" href="https://twitter.com/bantg">
              <img alt="User Avatar" class="twitter-avatar" src="https://storage.googleapis.com/papyrus_images/5f2fd50290bead37bc8610e165158b3d.jpg">
            </a>
            <div style="margin-left:4px;margin-right:auto;line-height:1.2;">
              <a target="_blank" href="https://twitter.com/bantg" class="twitter-displayname">banteg</a>
              <p><a target="_blank" href="https://twitter.com/bantg" class="twitter-username">@bantg</a></p>
    
            </div>
            <a href="https://twitter.com/bantg/status/1799189828619407749" target="_blank">
              <img alt="Twitter Logo" class="twitter-logo" src="https://paragraph.xyz/editor/twitter/logo.png">
            </a>
          </div>
        </div>
      
    <div class="twitter-body">
      package manager wars is better than the status quo. hope this will be distilled to something good soon. it’s in everyone’s interest.
      
      
      <div class="twitter-quoted">
        
  <div class="twitter-quoted twitter-embed">
    <div class="twitter-header">
        <div style="display:flex">
          <a target="_blank" href="https://twitter.com/fubuloubu">
              <img alt="User Avatar" class="twitter-avatar" src="https://storage.googleapis.com/papyrus_images/a3dd102fa9b443c95c2606a24748a268.png">
            </a>
            <div style="margin-left:4px;margin-right:auto;line-height:1.2;">
              <a target="_blank" href="https://twitter.com/fubuloubu" class="twitter-displayname">señor doggo 🏴🏴‍☠️ in his wartime ceo era</a>
              <p><a target="_blank" href="https://twitter.com/fubuloubu" class="twitter-username">@fubuloubu</a></p>
    
            </div>
            <a href="https://twitter.com/fubuloubu/status/1799172611882291292" target="_blank">
              <img alt="Twitter Logo" class="twitter-logo" src="https://paragraph.xyz/editor/twitter/logo.png">
            </a>
          </div>
        </div>
      
    <div class="twitter-body">
      Yet another federated package system that is not aware of other package systems (etherscan, VERA, blockscout, etc.), or languages (vyper, huff, fe, etc.)
      
      
       
    </div>
    
  </div> 
   
    </div> 
    </div>
    
     <div class="twitter-footer">
          <a target="_blank" href="https://twitter.com/bantg/status/1799189828619407749" style="margin-right:16px; display:flex;">
            <img alt="Like Icon" class="twitter-heart" src="https://paragraph.xyz/editor/twitter/heart.png">
            19
          </a>
          <a target="_blank" href="https://twitter.com/bantg/status/1799189828619407749"><p>5:20 PM • Jun 7, 2024</p></a>
        </div>
    
  </div> 
  </div><p>However, the biggest problem of them all is that there is a fundamental disagreement about what we can do about the problem. Many people think we just need one more tool to rule them all, but that's wrong because we already have dozens of tools with dozens of slightly different ways to accomplish the exact same tasks within different frameworks, and regardless no single tool is going to solve this problem sufficiently well for everyone. Some people think we just need to focus on how the data is being hosted, as if yet another SQL database is the solution to the problem, so long as we can force everyone to use a single database to reduce the problem to one that we can solve. A few out-of-the-box thinkers think that we can just leverage existing tools in specific ways to solve the problem better, and for the most part they are correct, except in small ways where we do have a specific set of requirements that most existing tools do not account for well.</p><p>No, the real problem is simply a problem of coordination, and we are not alone in having it. When you look at other programming language ecosystems, such as Javascript and Python, you can't un-see this coordination problem because the root cause is that developers think they can simply build their way out of the problem, and they don't realize that the first step to recovery is just deciding to work together and acknowledge that such a problem exists in the first place.</p><p>It is only with this enlightenment we can actually work to build solutions that truly push the needle.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/e41ecc4b9323314c7b5a47fbf650b82e.png" blurdataurl="data:image/png;base64,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" nextheight="499" nextwidth="740" class="image-node embed"><figcaption htmlattributes="[object Object]" class="hide-figcaption"></figcaption></figure><div class="relative header-and-anchor"><h2 id="h-inventorying-the-problem">Inventorying the Problem</h2></div><p>Okay, so we've taken the first step of admitting we have a coordination problem, what do we do next?</p><p>The second step in solving a coordination problem is finding the shape of the problem. Earlier this year, we interviewed several prominent teams who were building at different parts of the packaging spectrum about their processes, problems, and ideas they had for solutions. We collected the results and made an analysis of them, and recently published that here:</p><div data-type="embedly" src="https://github.com/ApeWorX/ethereum-packaging-interviews" data="{&quot;provider_url&quot;:&quot;https://github.com&quot;,&quot;description&quot;:&quot;Contribute to ApeWorX/ethereum-packaging-interviews development by creating an account on GitHub.&quot;,&quot;title&quot;:&quot;GitHub - ApeWorX/ethereum-packaging-interviews&quot;,&quot;mean_alpha&quot;:255,&quot;author_name&quot;:&quot;ApeWorX&quot;,&quot;thumbnail_width&quot;:1200,&quot;url&quot;:&quot;https://github.com/ApeWorX/ethereum-packaging-interviews&quot;,&quot;thumbnail_url&quot;:&quot;https://opengraph.githubassets.com/3e8bf9b62fa03aa92b5b67c4e8e7c3923f2005e35f278f4186ffb2603aeb5c3e/ApeWorX/ethereum-packaging-interviews&quot;,&quot;author_url&quot;:&quot;https://github.com/ApeWorX&quot;,&quot;version&quot;:&quot;1.0&quot;,&quot;provider_name&quot;:&quot;GitHub&quot;,&quot;type&quot;:&quot;link&quot;,&quot;thumbnail_height&quot;:600}" format="small"><div class="react-component embed my-5" data-drag-handle="true" data-node-view-wrapper="" style="white-space:normal"><a class="twitter-card-link" href="https://github.com/ApeWorX/ethereum-packaging-interviews" target="_blank" rel="noreferrer"><div class="twitter-summary"><img src="https://opengraph.githubassets.com/3e8bf9b62fa03aa92b5b67c4e8e7c3923f2005e35f278f4186ffb2603aeb5c3e/ApeWorX/ethereum-packaging-interviews" class="false"><div class="twitter-summary-card-text"><span>https://github.com</span><h2>GitHub - ApeWorX/ethereum-packaging-interviews</h2><p>Contribute to ApeWorX/ethereum-packaging-interviews development by creating an account on GitHub.</p></div></div></a></div></div><p>It is suggested that you read the report for more information, but we can summarize a few of the points:</p><ol><li><p><em>Make finding sources, compiler settings, and build artifacts (such as ABIs) as trivial as possible</em></p></li></ol><p>This one was our top finding. Almost everyone agreed that one of the biggest issues with DevEx across the entire stack is that it is difficult to find the information needed for downstream projects quickly, reliably, and correctly. In fact, they ranked it as the single highest issue preventing greater ease of developing new and innovative projects with smart contracts, for newcomers and advanced users alike.</p><ol start="2"><li><p><em>Make the solution flexible enough to handle complex environments, via old and new tools alike</em></p></li></ol><p>There is quite a lot of history now to EVM development, and one of the biggest problems to any potential solution these days is it must be able to flexible enough both to handle past projects, and also "level up" Ethereum DevEx with new innovations for years to come. If it's not flexible enough, really it won't be as useful as it could be within developer's stacks as they work on increasingly complex projects, so the value proposition is not there to justify upgrading. Also, if it's too difficult to use, that will also be a barrier to adoption, and prevent us from getting the results we need to in order to create better patterns of behavior and unlock better DevEx for more advanced use cases.</p><ol start="3"><li><p><em>Avoid centralized chokepoints, but also avoid DevEx issues that decentralized solutions have</em></p></li></ol><p>One of the biggest issues preventing greater use cases with smart contract data today is that the data ends up in centralized silos, from which it's hard to query across. If we want to be able to unlock massive wins on security and developer tooling, we need the ability to obtain large sets of smart contract data for machine learning, security trend analysis, and more. However, acknowledging that the data today lives in federated repositories which are already quite sticky to end-users, we need to create a pathway for greater interoperability of that data without accidentally threatening perceived competitive moats. In other words, our solution needs to show existing participants in our ecosystem why having a slightly smaller piece of a much larger pie is good for all of us.</p><p>If we use these desires as the starting point for assessing potential solutions to the problem, we can be sure that we will find something that most people find easy to use, flexible and powerful, and also compatible with all the ways that users want to interact with the data, both now and in the future.</p><div class="relative header-and-anchor"><h2 id="h-analyze-existing-solutions">Analyze Existing Solutions</h2></div><p>The next step in finding a solution to our problem is that we should assess what current solutions already exist, and compare/contrast them to see if we can find areas of improvement or requirements a new solution must have to be compatible with what users have come to expect.</p><p>In terms of current solutions, there are couple of ways that people build and share sources, compiler settings, and build artifacts today:</p><ol><li><p>Publish their project to Github, usually just the sources, framework-specific compiler settings, and dependency information that other tools have to add custom handling if they want their own users to download them as dependencies within their own projects</p></li><li><p>Publish their smart contract code build via block explorer verification, either by flattening code or through multi-file verification (in both cases manually specifying compilation settings), which others (primarily security researchers or those scripting in non-EVM environments) can consume</p></li><li><p>Manually create some build artifacts locally to try and match what is expected to interact with on-chain (for example, using Curve from a Solidity project, or working with a contract that has a corrupted ABI published on etherscan or no ABI at all)</p></li></ol><p>There are also a couple of recent developments we can check out:</p><ol start="4"><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/mario-eth/soldeer">Soldeer</a> shipping foundry-specific package management as a core feature <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/m4rio_eth/status/1798917098699464935">within Foundry</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/vyperlang/vyper/pull/3891">Vyper v0.4</a> will ship with a zip archive-based packaging of an existing project's sources and settings for near trivial rebuilding of any vyper contract (such as for verification purposes)</p></li></ol><p>Additionally, we can think outside the box and compare our needs to those other open source packaging communities have adopted:</p><ol start="6"><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.npmjs.com/cli/v6/configuring-npm/package-json">NPM</a>, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://packaging.python.org/en/latest/specifications/binary-distribution-format/">PyPI</a> (and other language communities) have quite large and successful repositories of source-available package data useful for composing within other projects using standards</p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://nixos.org/guides/how-nix-works/">nix</a> is a functional language that allows specifying how to build packages from scratch reliably and without dependency issues because you specify complete dependency information</p></li></ol><p>Lastly, there is also <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-2678">EIP-2678</a> (aka EthPM v3), which was an attempt to solve this problem many moons ago, and (as I stated before) is in use within Ape (albeit in a slightly-modified form) to a great degree of success in reducing pain emanating from a multi-framework universe of different build systems we need to handle for our users.</p><div class="relative header-and-anchor"><h2 id="h-finding-patterns">Finding Patterns</h2></div><p>Obviously, one of the biggest differences in comparing our needs to those of the packaging systems in use by some of the biggest language communities is that our ecosystem is inherently <em>multi-language</em>, meaning we have to take all comparisons with a grain of salt because we are well past the point where focusing only on a single language community is even practical for EVM development (with the rise of Vyper, Huff, many new language communities being built for L2s, etc).</p><p>That makes the recognition of something like nix interesting because it is inherently language-agnostic, which is critical for us both in terms of the EVM language we want to work with as well as the way we want to consume this information (for use within frameworks and devtools written in JS, Python, Rust, Go, etc.), and is basically a requirement for any prominent EVM devtool in this day and age. Still, something like nix may be way overkill for what we need as it's not always practical to ship what is essentially an entire functional OS as a dependency in all the different environments we need to work with today (such as the web browser).</p><p>What these all have in common though is that there is a <em>single common package specification</em>, so that even if multiple tools or languages are used, we can be sure that they work with the same data in a context-independent manner, no matter what tool is currently <em>en vogue</em> (and what other tools are no longer in style that we still need to work with).</p><p>This is what building in a future-compatible way looks like.</p><hr><p>The second thing we can see is that there is a stark divide between "filesystem-like" archive formats (e.g. git/Github, PyPI/NPM, soldeer/vyper v0.4 zip archives, etc.) and "virtualized" document formats (e.g. JSON documents from REST APIs like etherscan, EthPM, etc.) that we can work with. It's also worth noting that while REST APIs (which communicate via JSON documents) can obviously be a convenient way to index and share metadata for packages, it's not actually a convenient way to share source files or even hierarchical information about file layout for reproducing a build. All "virtualized" formats end up needing to "re-create" the filesystem context based on the metadata that it has, which may run into difficulties where such metadata is under-specified.</p><p>Since most successful implementations of this idea use an archive format (the most common of which is a zip archive of a particular folder structure, with defined files in it, where the archive has a special extension), we probably want to use the same thing in our solution, but also be smart about what metadata we want to expose for easy access within the archives, for use cases such as querying packages from a repository or pre-determining what build artifacts we will have access to once we completely build the package.</p><p>Which takes us to...</p><div class="relative header-and-anchor"><h2 id="h-building-another-standard">Building A(nother) Standard</h2></div><p>We likely have yet more to do in inventorying, analyzing, and finding patterns vs. what exists out there, but I am gonna walk through what comes next after we do that. Namely, everyone's favorite XKCD comic:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/8fe8a2a7e3479a68f0e3088a4008376e.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAASCAIAAAC1qksFAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEZ0lEQVR4nI2UQYTzWhTHbzfdfIsyDJ8xDBUqhDBUCcOVRQ0lhMoihEspIVwuIQyhlFmES8kilBDKtwhdlFBKF2XIoosyzKKUWQxdDEMWoXRxn+l9X1+f5z3vt4hLrvO/55z/OeB4PLITx+PxcDjwc6/XEwRhOBx6nletVgVBuLm5AQDIshxF0fX19e3traZpP378uL29rVQqlFIe4TIIB5RlWRQFY2y5XNZqNdu2LcvSNA0AUKvVTNOEEAIAKpXK1dUVAKBarTYaDVmWq9WqJEn39/cAAH4YjUbdbjfLMsZYURRlWR4OB2BZVhzHYRgOBoNOp4MxdhzH8zzbth8fH23bNk3TMAxd1wkhtm33ej3btgkhjuMMh0NCCEKo2WwKgnB/fy+KouM44/GYUjqZTL4fOhqNeHbnpPj55eUFIeT7PsY4yzJFUWRZdl3Xtm3f9wkh+/2eMbbb7QaDAU8OACCK4mq1YoyVZckYI4T8KcDTOX8ZY6vVqn/CdV1FUe7u7kzTdBxHEIR6va5pWrPZ/DxBCHl6ekqSJI7jJEn2+/3xePz6+vqbwGVnzhn0ej3thGmaqqoihBzHwRgbhgEhVFV1Op3O53NCyHK5vCzDudXfAkmS8OZQShFC3W633+/Hcfz29vb4+NjpdERR9DwPQliv1yVJ0nU9iiL5BO+z67p5nsdxrGna8/OzYRgIIU3T5vO57/vfAkEQGIZh27aqqoZhaJo2GAw2m41pmt1uV5IkhFC/34cQWpaFMRZFUVXVVqvVaDRc1/U8L8/zJEl0XbcsC0LY7/cVRaGUfgvEcZznebvdbrVaQRB4nieK4vv7+2azQQglSQIhHA6HrVbr6uqKu5BSOpvNsiwbjUZZlhFC1ut1nuedTkdVVd/3Pc8TBKEoiqenJ0ApzfNc13VRFBVFQQiJophlWZ7nCKEsy2RZDsPQ930IISGEe1ySpJubmyRJiqJwHGe1WqVpihCSZVlRlG63K8vyfD53XRd4J7id2+22YRitVktV1dlsZlkWY2y73U4mkziOJ5MJY+zr62uxWCyXyzAM9/v9x8cHISTLMgghxljXde4IXdfb7bZlWWA8Hr+/v19fX0uS1Gg0KpVKs9l8fX3dbDaGYXAzxHE8nU6DIGCMjUYjeGK32zHGPj4+MMZ5nr+9vdVPyLJcq9UEQdjtdt8liqKoLMsoimazWZqmv379Go/Hn5+f6/XaNE3uvKIoAACLxYIn9PPnT0VRuCO5wMvLS1mWSZJMp9P0RBiGx+PR87x/neQ8z88C+/2+VqulaXoWG4/HlwJ8ei+D/DUH50Hju/A8I5cCh8Oh0+lst1veAwjher3+p8BlEL4OvpvMNy1fEpzzqjAMg59fX191XedRttstdxd/8m63wxjz6l0G4RsaY/y/SrT4DWOMOzhNU/6Lu+i/SvTw8JAkCaV09BtKaRiGhBBZloMgCMMwCIIoivid5+fnMAyHwyGlNIoi13V1XccYny9wgiBI01QQhD8Au+8C7nYSC4YAAAAASUVORK5CYII=" nextheight="283" nextwidth="500" class="image-node embed"><figcaption htmlattributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>But seriously, we can already see that creating a standard will be an extremely useful to formally specify a format so that other tools and languages can use it, and we can avoid siloing information and unlock the potential that broad accessibility to smart contract data can give us. Thankfully, we already have the EIP process for doing this (most likely should be developed as an ERC), as well a previous examples (namely EthPM <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-190"><s>v1</s></a> <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-1123"><s>v2</s></a> <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-2678">v3</a>) that we can use to reference what information was deemed important to share in the past.</p><p>Since we are already talking about departing from the previous standard and adopting an archive-like format instead, we can probably not tether ourselves to the <s>mistakes</s> designs of the past and also establish a more reasonable scope for what such a format must satisfy and what it can leave up to future iteration. This will likely take many months, inevitably some <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://effectiviology.com/bikeshedding-law-of-triviality/">bikeshedding</a>,  and likely a hot discussion or two, but ultimately what we are building is a strong, framework-independent, multi-registry compatible format that we can start to use to solve production issues, and not just for one particular user or use case but <em>across the whole ecosystem</em>. Doesn't that sound great?</p><div class="relative header-and-anchor"><h2 id="h-getting-standards-adoption">Getting Standards Adoption</h2></div><p>The last step in our journey is getting (mass) adoption of our new standard, which is where it goes from being another unfortunate piece of roadkill in a long list of poorly adopted Ethereum devtool standards, to ultimately what we need to hyper-accelerate Ethereum DevEx and create the smart contract data packaging of our dreams! Probably easier said than done, but fortunately we have already interviewed many major players in the Ethereum dev stack to get their input.</p><p>The only question that remains to be answered by them (and you, reading this article) is:</p><div class="relative header-and-anchor"><h3 style="text-align: center" id="h-will-you-join-us">Will you join us?</h3></div><p></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
            <category>#ethereum</category>
            <category>smart contract dev</category>
            <category>engineering</category>
            <enclosure url="https://storage.googleapis.com/papyrus_images/872ed9853f8186c80a60b32eee51df82.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Real Time Operating Systems]]></title>
            <link>https://paragraph.com/@apeworx/real-time-operating-systems</link>
            <guid>TdcEKxlTohLQEg2g0aKc</guid>
            <pubDate>Wed, 22 May 2024 23:20:22 GMT</pubDate>
            <description><![CDATA[A big part of designing systems that are reliable and secure enough to be trusted even under the harshest conditions is the concept of timeliness. If...]]></description>
            <content:encoded><![CDATA[<p>A big part of designing systems that are reliable and secure enough to be trusted even under the harshest conditions is the concept of timeliness. If you are doing an important task that requires constant diligence and it is critical that your answers are timely in order to be considered correct, then it doesn't matter how perfect your algorithms are if you are operating on incoming data that's just a little bit too old.</p><p>Systems that have to adapt and respond in real-time have to take special care not only to ensure that they are reacting as quickly as they can, but that the way they are acting, especially under the presence of faults and uncertainties, produces a reliable and stable outcome no matter what else is happening around it. You may even be surprised to learn that the number one determination of safety in these types of systems is actually <strong>not</strong> how <em>fast</em> they react, but rather how they ensure they have the <em>most correct</em> response despite dealing with adverse conditions and having a limited time to make decisions.</p><p>You can actually think of application blockchains like Ethereum as real time systems. They respond to complicated conditions and dynamically adjust to the presence of faults, almost entirely without any human intervention whatsoever. But let's focus on what makes them actually "real-time" in the sense of being a system that has to maintain liveliness no matter what else is going on, because some of the best properties that make Ethereum an attractive place to use for serious, high-valued applications are the reliability and fault tolerance emanating from this design principle.</p><div class="relative header-and-anchor"><h2 id="h-soft-real-time-vs-hard-real-time">Soft Real-Time vs. Hard Real-Time</h2></div><p>There are plenty of examples of real-time systems where not making a decision in a timely manner critically affects how safe the system can actually be. Airplanes for instance are some of the most critical and high-reliability systems we interact with on a regular basis. When flying, airplanes have to make quick adjustments to their flight control surfaces in response to unpredictable and often chaotic movements of air around them that if left unchecked for too long would lead the airplane to tumble out of the sky and crash. Quick, timely inputs are absolutely critical to flight safety.</p><p>To account for this, aerospace engineers design their systems with <strong>hard</strong> real-time constraints, meaning that no matter what happens with the software it <em>must</em> always respond within a short time period or it will risk losing control of the entire aircraft. This property holds even if it means abandoning a calculation you have already started but not completed yet, as a result provided after the expected deadline is essentially useless to maintaining control.</p><p>Not all real-time systems need to maintain this level of strictness however. Sometimes, while we still do care about timeliness in a relative sense, but we can be a little flexible on the actual deadline so long as it means we are providing a correct answer, as long as that answer doesn't take <em>too</em> long to compute. In fact, we can describe this as more of a spectrum: the longer it takes, the less useful the computation will be to the system, but that usefulness is not black and white like it is with hard real-time systems. We call this type of system a <strong>soft</strong> real-time system.</p><p>We could describe blockchains like Ethereum as being soft real-time systems because while they do generally target consistent block confirmation and slot finalization times, they can occasionally not come to consensus for time periods a little longer than their targets and still maintain adequate safety. Still, their timeliness guarantees are important, because without them the lending and borrowing systems, margin calls, liquidations, oracle price updates, etc. become a little too out of date, and those applications dependent on those system-level guarantees inch closer towards catastrophic outcomes.</p><div class="relative header-and-anchor"><h2 id="h-tortoise-and-the-hare">Tortoise and the Hare</h2></div><p>While speed is nice because with more speed we can fit more computations, as we said before, the primary determination that a system will be successful in it's goals is that it is capable of delivering consistent, reliable, and <em>timely</em> results. If you have a system that produces a burst of computations at random times, and is not capable of scaling to meet that demand within the time period required, it could overrun the expected deadline, which to a soft real-time system may mean that the results you produce could be considered <em>out of date </em>by the time the actions are taken. In the context of a smart contract application that runs on an application blockchain, if we take longer than a full block period to produce an action in response to some conditional trigger that we'd like to land in the next block, then our action may no longer be consistent with the state of the blockchain where we decided to take that action if it takes too long.</p><p>How we design off-chain systems that interact with on-chain ones should also reflect this principle. That doesn't mean we should go out and pick the fastest tools for the job always, because what works most of the time may not work in periods of high demand. We should build off-chain systems that <em>scale well</em> in response to events on-chain, so that when those times come, we are ready for them. This may mean picking algorithms and architectures that emphasize more of an approach of performing measurements continuously in parallel with actions that we want to trigger based on those measurements. Searching for a good opportunity to act in a real-time system is actually more about anticipating the best move to make next, vs. blindly reacting to every event that is happening in an effort to keep up with others.</p><div class="relative header-and-anchor"><h2 id="h-and-gorrillas-oh-my">...and Gorrillas, oh my!</h2></div><p>No thought piece would be complete without a good shill, and I really started thinking about writing this short article in response to a discussion on the design principles of our upcoming <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/ApeFramework/status/1786488208831762855">Silverback Application Platform</a> product with my development team. As people are starting to build out their own applications using the fully free and open-source Silverback SDK (<em>you are trying it, aren't you anon?</em>) we hope they will incorporate some of these design principles in their work and remember to always pick the solution that favors <em>timeliness</em> and correctness over speed and algorithmic complexity. Sometimes it really is the slow and steady that wins the race!</p><p>Happy hunting apes</p><p></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
            <category>smart contract dev</category>
            <category>security</category>
            <category>trading</category>
            <category>engineering</category>
            <category>python</category>
            <category>#ethereum</category>
            <category>#crypto</category>
        </item>
        <item>
            <title><![CDATA[Ape has you covered: All about coverage (Part 2)]]></title>
            <link>https://paragraph.com/@apeworx/ape-has-you-covered-all-about-coverage-part-2</link>
            <guid>JbQ3WSHTtObFxen97KbY</guid>
            <pubDate>Thu, 24 Aug 2023 20:33:16 GMT</pubDate>
            <description><![CDATA[Ape has you covered: All about coverage Part 2Before you start delving into the practical aspects, it is essential to understand the concept of code ...]]></description>
            <content:encoded><![CDATA[<div class="relative header-and-anchor"><h1 id="h-ape-has-you-covered-all-about-coverage-part-2">Ape has you covered: All about coverage Part 2</h1></div><p>Before you start delving into the practical aspects, it is essential to understand the concept of code coverage. If you are unfamiliar with coverage, we recommend referring to our <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/apeworx.eth/caqyeWaMPu_0USXNa1CJlCYrmTx5-F6jNbyuBmyycyk">first article on the subject.</a></p><p>The latest update, version <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ApeWorX/ape/releases/tag/v0.6.13">0.6.13</a> of Ape and version <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ApeWorX/ape-vyper">0.6.9</a> of ape-vyper, introduces the coverage support exclusively for Vyper contracts. However, since Ape is a plugin based framework, this system facilitates adding coverage support for other languages, such as Solidity and Cairo.</p><p>So without further ado, lets dive in:</p><hr><div class="relative header-and-anchor"><h1 id="h-demonstrating-coverage-with-a-token-contract">Demonstrating Coverage with a Token Contract:</h1></div><p>In this article, we are going to employ a Token contract as an illustrative example to showcase the functionality of coverage. You can follow this link here for the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/dtdang/TestToken">repository</a>.</p><hr><div class="relative header-and-anchor"><h1 id="h-how-to-use-ape-coverage">How to use Ape Coverage</h1></div><p>Utilising coverage functionality within the Ape framework is straightforward. You can initiate coverage by including the `--coverage` option when running `ape test`. This will generate a comprehensive coverage report. It is worth noting that certain types of coverage will require a provider plugin that supports transaction tracing such as `ape-hardhat` or `ape-foundry`.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.apeworx.io/ape/latest/userguides/testing.html#contract-coverage">https://docs.apeworx.io/ape/latest/userguides/testing.html#contract-coverage</a></p><p>This is our token contract for this example:</p><img src="https://storage.googleapis.com/papyrus_images/27836bb4e80ab4da82b858dcd04a4ef3.png" blurdataurl="data:image/png;base64,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" nextheight="1600" nextwidth="1319" class="image-node embed"><p>Currently we have not set any tests for this contract so our coverage will show  0%.</p><img src="https://images.mirror-media.xyz/publication-images/fP_vx4UB9KLrNH-D2z-94.png?height=378&amp;width=924" alt="" title="null" class="image-node embed"><p>Ape shows the name, statements (Stmts), misses (Miss), coverage (Cover), and functions (Funcs). This is modelled after coverage-py and pytest-cov style reports.</p><ul><li><p>Name: Name of the source identifier</p></li><li><p>Statements (Stmts): Amount of statements present in each contract</p></li><li><p>Misses (Miss): Amount of statements not covered in tests</p></li><li><p>Coverage (Cover): Percentage of the contract that is covered by tests</p></li><li><p>Functions (Funcs): Percentage of functions/methods that are tested in each contract</p></li></ul><p>A statement is either a group of values that have the same line numbers in a source file or it is a value with an extra tag to identify builtin logic that is injected by the compiler (such as the default or fallback method).</p><p>The coverage report is normally generated in the terminal but you can also generate the coverage reports as an external XML or HTML files by configuring them in the `ape-config.yaml` like:</p><img src="https://images.mirror-media.xyz/publication-images/TwOSebupWHF4AmK2JlqBT.png?height=490&amp;width=1278" alt="" title="null" class="image-node embed"><hr><div class="relative header-and-anchor"><h2 id="h-thorough-code-coverage">Thorough Code Coverage</h2></div><p>You can also see a more verbose coverage report by setting the field `terminal` or `html` to include `verbose: True`. Verbose outputs are useful when you are trying to find the missing areas to cover. This will break down each contract to show each function and how well the functions are covered individually.</p><img src="https://images.mirror-media.xyz/publication-images/1jNFb1mI8Xy219hc9-sRc.png?height=528&amp;width=1398" alt="" title="null" class="image-node embed"><p>This will result in the following output for our contract `TestToken.vy`:</p><img src="https://images.mirror-media.xyz/publication-images/-MtTz7UeUO8LIdSCfb-d3.png?height=824&amp;width=790" alt="" title="null" class="image-node embed"><p>The `_*builtin*_` functions listed under your contract coverage functions are the functionalities that the compiler uses internally that are not in the source code, such as non-payable checks, safe-math checks, and the not-implemented contract default method check. Tests for these conditions are necessary to get to 100% coverage</p><hr><div class="relative header-and-anchor"><h2 id="h-excluding-methods-and-contracts">Excluding Methods and Contracts</h2></div><p>Like <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.apeworx.io/ape/stable/userguides/testing.html#gas-reporting">gas reporting</a>, you can also exclude contracts and methods from tracking coverage using your `ape-config.yaml` file.</p><img src="https://images.mirror-media.xyz/publication-images/n9S15SCqQpEAZzw7MuHgZ.png?height=482&amp;width=1600" alt="" title="null" class="image-node embed"><p>You may want to use exclusions for methods or contracts that you don’t plan on pushing to production but are still using for debug or testing purposes.</p><p>We will be excluding the `DEBUG_mint` function from testing.</p><hr><div class="relative header-and-anchor"><h2 id="h-adding-coverage">Adding Coverage</h2></div><p>Now let’s try and add some coverage for our `TestToken.vy` contract.</p><p>Some methods will show zero statements. One example with a zero statement may be from an auto-generated getter method for a public variable: certain versions of Vyper do not contain source mappings for these methods. However, Ape will still check to see if this method has been called in your tests. To get 100% coverage, you must call these methods in your tests.</p><p>In this case, these will be methods like `name()`, `symbol()`, `decimals()`, `totalSupply()`, `balanceOf()`, and `allowance()`. A simple example of tests that you can make for these are:</p><img src="https://images.mirror-media.xyz/publication-images/-Q90OuicnLIyLH0d4XrCJ.png?height=452&amp;width=958" alt="" title="null" class="image-node embed"><p>By just adding this test, the coverage report for the TestToken contract will now show:</p><img src="https://images.mirror-media.xyz/publication-images/QJB_Ipzv29eCW1SsDbnbo.png?height=788&amp;width=806" alt="" title="null" class="image-node embed"><p>So now all we need to do is to add tests for the other functions: `approve()`, `transfer()` and `transferFrom()`</p><img src="https://images.mirror-media.xyz/publication-images/mX3eFvkUkkUSrqhfmNyYR.png?height=638&amp;width=1110" alt="" title="null" class="image-node embed"><p>By incorporating these small tests, our test coverage will now reflect that we have 100% coverage for these functions.</p><img src="https://images.mirror-media.xyz/publication-images/A47qj3oZELOUzoO8WMLYF.png?height=788&amp;width=806" alt="" title="null" class="image-node embed"><p>However, it is crucial to recognise that achieving full function coverage does not guarantee thoroughness in testing your contract.  “Are these tests adequately comprehensive for my contract?” While the introduced test may offer substantial coverage, it is important to acknowledge that they may not encompass every possible scenario in which your contract may execute. Even with diligent testing and high code coverage, there is always room for enhancement. The journey towards code perfection is a continuous one.</p><p>Currently we only support statement coverage right now, if you were to add branch coverage, it would show less than 100% for total coverage.</p><p>One more thing to note is that some methods may have a full method signature while others do not. Methods that have the full signature mean that their short name is shared with other methods. This happens in Vyper from auto-generated kwarg-based methods, or in Solidity when overloaded functions are added. Thus, the full selector is used to distinguish the methods in the coverage (and gas) reports.</p><hr><div class="relative header-and-anchor"><h2 id="h-using-coverage-responsibly">Using Coverage Responsibly</h2></div><p>Remember in our previous article that we said “Code coverage metrics, as a percentage score, are really telling you very little about whether your code is doing <em>the right thing</em>.” Writing an abundance of tests is not the sole objective.  Instead, it is crucial to focus on crafting tests that align closely with your specific objectives, ensuring optimal suitability and effectiveness. The coverage tool serves as a means to gauge the extent to which your code has been thoroughly exercised with these examples, or guide you towards areas that need more attention.</p><p>We trust that this article has provided valuable guidance on harnessing Ape&apos;s new coverage feature to prepare your contracts for production deployment. It is important to remember that while coverage is an invaluable tool, it should be supplemented with other methodologies to ensure the overall safety and security of your contract.</p><p>Consider complementing code coverage with techniques such as fuzzing, red teaming, and exploring unconventional attack vectors. By adopting a holistic approach to testing and security analysis, you can fortify your contract against potential vulnerabilities and mitigate risks effectively.</p><p>Embrace the power of comprehensive testing strategies and exploit the full potential of code coverage as a part of your robust development and deployment pipeline.</p><p>Thank you for reading and enjoy our coverage tool!</p><p>- ApeWorX</p><hr><p>For the latest on all things Ape follow us on: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://apeworx.io/">Apeworx.io</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/invite/apeworx">Discord</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/ApeFramework">Twitter</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://staging.bsky.app/profile/apeworx.io">Bluesky</a></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/27836bb4e80ab4da82b858dcd04a4ef3.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[How to Build a Crypto Project like an Aerospace Engineer]]></title>
            <link>https://paragraph.com/@apeworx/how-to-build-a-crypto-project-like-an-aerospace-engineer</link>
            <guid>WsAR6jQemz1k6jwDTK39</guid>
            <pubDate>Fri, 28 Jul 2023 21:39:18 GMT</pubDate>
            <description><![CDATA[Within Crypto, I don’t think there’s a single truism more often stated than “we should build smart contracts like airplanes, not iPhone apps!”In fact...]]></description>
            <content:encoded><![CDATA[<p>Within Crypto, I don’t think there’s a single truism more often stated than “we should build smart contracts like airplanes, not iPhone apps!”</p><p>In fact, just the other day someone shared this with me:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/jessewldn/status/1683805696297406465?s=20">https://twitter.com/jessewldn/status/1683805696297406465?s=20</a></p><p>But no one ever tells you how to actually do it. How does one shift their skills, thought process, and mindset away from building and launching projects rapidly to building them like they’re flying to the moon? Where’s the handbook for learning how to do this? Why can’t anyone tell me?</p><p><em>*Crickets.*</em></p><p>Well, thankfully, I actually happen to have a background in both hardware engineering and building aircraft, and I’ve also been working on building smart contracts for almost as long as my previous career as a flight control engineer. I’m gonna give you all the secrets that no one seems to want to share about how to build projects that always work, never get hacked, and make you millions in the process.</p><p>…</p><p>Okay, so I can’t actually do those things, but I have your attention now don’t I?</p><p>Alright, what are these pearls of wisdom?</p><div class="relative header-and-anchor"><h2 id="h-failure-is-not-an-option">Failure is not an option</h2></div><p>It’s just reality.</p><p>All software projects have failures. What sets apart <em>good</em> projects from <em>great</em> ones isn’t how perfect the code is, or how much was spent on audits, or even how big the test suite is; it’s way simpler than that:</p><p>It’s <strong>planning</strong> for failure <em>before</em> it happens.</p><p>If you can’t reason about and rattle off a dozen or so failures that could happen when launching your brand new application, you’re doing it wrong. The weeks you spent working on gas optimizing your code so that it’s as efficient as humanly possible would be better spent making sure that you not only understand in what practical ways the code <em>could</em> have a failure, but also what <strong>mitigations</strong> you may have (or make available to your users) so that the impact of those failures is as minimal as possible.</p><p>In aerospace engineering, one of the tools that gets used is to conduct a <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://en.wikipedia.org/wiki/Failure_mode,_effects,_and_criticality_analysis">FMECA</a> (or Failure Modes, Effects, and Criticality Analysis) study of the system, identifying all the possible failures that the system can have, for all of the complex components within the system. This analysis is performed during the <em>design phase</em> of the project to ensure that there are protections and mitigations in place for when different types of components (hardware, software, hydraulic, electrical, etc.) have some fault that affects their operation and impacts other components around them.</p><img src="https://storage.googleapis.com/papyrus_images/d79790215d94885973f0fcc10ac81055.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAOCAIAAADBvonlAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEL0lEQVR4nHVSTWzbZBh+z1zRDrBOgm1XJE4ITRw5ggCxCpDY4ICKplGBOEzqYbBpiEoDIQadNITQpnWoY+pvmmZN0rRuljRp0ziuayduHP/EX1wnThzHSeM6P66RXdrCgUePXn36Du/z833gOE7PtsOrUWxlpVbTer2eZVmmuW96aLfbx4d2u23btnME27Z7/8L/XYLjOK26vp3YZAsFmqYJgqBpmvKQy+VKsizwvCSJvIdut2vbdt/uO45TUSvVWrWqVbW6pulaBIsEFgMUTTWaRk2rtlqGopRs23YFFIYhnkwR21QymWRZVkIoxzDpNE4QW7reOHCcvrvUdg5cg4c2HccpSSU8gRfzRWI9k46nn4Wj4fkwmSLxBI4nyWAwuby84TgHroA/lnq0lAxG1sLYOo+qSq1F0tyfE9PjEzPhSEwuG0iuSXLNtHody0IIsQW22WjOrMy+df2dy7c/ff/bi4O3Pvx49PLgrQ8+Gb309si7ow+HiuLXma0btu0JILW1U9RQuSWVW4VijRXULFeO0WKSlhJMaSPnMr0j71td0zRVVSW2iL363pWxq/ASwMsAZwDOAgwAnAd4AeB5gIuwZ0EBQa/nCchlPc9XWEFlBbVQrPGSRvCVKZx7vMkFKbS5I8eZEwFFUeLxeMfoDP38ObwIrsZpT2PAm68BDMKFESghSKShf5hAUQ1OrPKSVijWDsnw5XWcwbfZDMlKSCuVDRFp+127oet+vz+Fp+yO/cVvw67x8wDnvHkW4BS895PrnSlC0wJeOUqwJaiLW3y6oIhIYwVVkPUUkZ+Y9E/OhaZ94bnA8jrOZAu7bdMyjMZCIBCLx/pmf+iOl+CMV8sAwKsAF+DqGNQN8N8H/2cwew0ODr8pKus0V2aP7PNIz5DsvD88Nx+enPY/nvTNzYcSKarZMg2jEYlENlIbVVQd+vWK6/0cwHNu71+NAV+CguQmmPkIfgCX9qHArmrkebd91iOP6jjNT8yGZp6uPpwKYKnss0yeEdRO19Z1PRqNnrzBaa+Z1wHegAcLwMowcR2wa3Db234TjhKotZaI6pLcEFGdR5qItM2d3fFk/tFG4W6UHk/mn5JSlEbdrl2v1+fmfBki09vrDd8bhlMAr8BfT8A3CdscLNbgrrf6mP8kSOBZXzAeiCSwjSwpVjmk4VnxwcLqfV9kJraFZUsYjdI7u5bVbxpGOp1eS8TNhvX9+JfwJsAlCIchHoHZbwAbhe+8vSPevHGcIMbKs2kuRAlYVooxMiOoFFcJUWKIFIKUGKCKS9kSxZXbZtey9lW1ShCboqgXuJt7FqgGSCpUjf8YP6zoJAGZIrEAthZZyzOCojZLZYNlUWwpHltKxLH1aDgWjeE4X+l0e6Zp8jxPkoSiGNncH3kRcixQechzcA/gF4AfAcY8gTsAv8PAgeP8DQF4sbwbKlojAAAAAElFTkSuQmCC" nextheight="542" nextwidth="1221" class="image-node embed"><p>Typically, this process leads to designing physical redundancies and failure handling into the system, so that in case an issue occurs, the system has an adequate chance at surviving the incident, as well as minimizing damage to itself, it’s environment, and the occupants inside. This process leads to the creation of a <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://en.wikipedia.org/wiki/Hazard_analysis">FHA</a> (or Functional Hazard Assessment) which is the high-level overview of the major faults that bubble up from the FMECA study, and what the likelihood and impact of any critical events would be. All of this analysis occurs in the <em>design phase</em> of the aircraft, meaning years before you even get to build your aerospace project, you are aware of every single major fault of the system that could ever happen in practice.</p><p>Thankfully, smart contracts aren’t nearly as complex as aircraft are, and there’s a fairly known set of issues that can occur with them, so you can conduct a rigorous analysis like this using available tools (and a little imagination), and can pretty much figure out all the worst case scenarios within a day or two; a week tops. You also don’t have to do this before you get approved to build your project, as that is driven by FAA regulatory requirements meant to enhance the success of new aerospace projects (even though it creates a lot of overhead to the design phase).</p><p>Which brings me to my next point…</p><div class="relative header-and-anchor"><h2 id="h-it-has-to-work-every-time">It has to work, every time</h2></div><p>Well, not really.</p><p>Or, I guess I should say that the steps you take along the way don’t necessarily have to all work out of the gate. It’s the final product that counts.</p><p>A good practice when designing a new complex system is to identify the things that are <em>novel</em>, and then identify things where a pretty common approach or the solution already exists. Once you’ve done that, you can minimize the set of things that you need to <em>experiment</em> with first before you’re ready to combine it all together for the final product (which if you’ve done your experiments well should indeed work pretty well).</p><p>In aerospace, there is a tool called <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://en.wikipedia.org/wiki/Technology_readiness_level">TRL</a> (or Technology Readiness Level) which is a very cool framework invented by NASA that attempts to classify the maturity of technologies, classifying their progress from ideation, to simulation, to lab testing, to first flight, to heavy use in production. The idea is that if you can classify the TRL of all the major components of your system, then you can identify which parts are indeed <em>novel</em> (meaning there doesn’t exist a mature option you can use) and which parts you can find alternatives for that work well enough for your intended use cases. By doing this, you can increase the <em>aggregate</em> <em>maturity</em> of your project, and give it the best chance for success, since you’ve minimized the amount of “new things” you are working with that require enhanced verification work before launch.</p><img src="https://images.mirror-media.xyz/publication-images/ca4m6bRBOR0RpR6w-HRPE.png?height=1046&amp;width=948" alt="NASA&apos;s TRL scale" title="null" class="image-node embed"><p>This is a good skill to learn, many engineers at the highest level get pretty good at researching and identifying pieces of technology that meet the needs of the project, and reduces the amount of new code that needs to be created. In Crypto, this is a <em>necessary</em> skill because creating new code has a much higher barrier to cross in order to “qualify” it for production (testing, audits, etc.). Basically, reuse what you can and focus your innovation on what is truly innovative.</p><p>But most of all, the only really true test of secure software is simply how much <strong>exposure</strong> it has had in production, basically a crude calculation of how much time it’s been in that environment, at intended levels of use (the more the better), as well as the range of use cases that it has successfully solved without failure. Software components with a high “TRL” score very highly in all of those dimensions.</p><p>Let’s take a practical example, say you’re designing a new bridging protocol. You want to make an innovative cross-chain asset transfer system by having mirror tokens on other networks. To do this, we also need to establish a trading market for those tokens to retain their relative worth. Well, part of that system actually already exists, since we can use Uniswap’s AMM (which is deployed on multiple chains) to ensure that bridged assets retain close parity with their own copies on their originating chain. It makes no sense for us to reinvent the wheel here, this project already works quite well in production, and it’s not the core innovative component we are developing.</p><p>Since we’re using an established, mature component for that part of the project, that means we can focus more on the innovative and difficult parts, which makes the overall project much more likely to be successful. And that’s great because…</p><div class="relative header-and-anchor"><h2 id="h-you-only-have-one-shot-to-make-it">You only have one shot to make it</h2></div><p>The last point in the tweet about having a “[limited] number of shots to achieved PMF” (product market fit, for those who don’t speak VC) is definitely very true. But it’s also predicated on a lie.</p><p>Let me explain.</p><p>The lie is that you need to achieve PMF almost immediately, since the amount of time it takes to “qualify” your software for production is so high, it really limits the amount of times you can spend rebuilding everything from scratch.</p><p>Wait, why are we rebuilding things from scratch?</p><p>We covered this in the previous section (kinda), but if we’ve done a good job at reducing the number of truly <em>novel</em> ideas we are trying to explore, we should set ourselves up for success because we don’t actually have to rebuild everything from scratch, just the parts that didn’t work as we expected.</p><p>You see, the best way to be successful in building complex systems is breaking them down into smaller, self-contained components that can be independently iterated upon and tested before being combined into the larger application.</p><p>This is the part that is probably hardest though, because the ability to truly “test” novel smart contract mechanisms is pretty hard, mostly because the “complex” part of the system happens to be the Cryptoeconomic schemes we are all trying to play with. We don’t truly know how to simulate and test those (outside of simple modeling), so our only choice is to “test in prod” (aka <em>experiment</em> on live, willing degens) once we’ve reached the limit of what local testing and simulation can show us.</p><p>So, there’s nothing we can do?</p><p>Well, we can take another page out of the aerospace handbook and follow a tiered approach to testing and release to de-risk the likelihood of failure at each step (as well as increasing our chances of hitting PMF, if done correctly). Actually, one of the reasons that we created the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://chaos.apeworx.io">cHaOSneT</a> ephemeral testnet product was that we think there’s a gap between local testing and production which needs to be filled by a full <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.aerospacetestinginternational.com/news/products-services/hardware-in-the-loop-testing-technology-center-opened-for-aerospace-firms.html">system-in-the-loop integration testing</a> platform, and which can also be used to run full-stack simulations of our components, pre-launch “public” testnets for our userbase, and continuous “fire drills” (post-launch) for the team maintaining the project in a controlled environment, with limited impact for project teams and their users. The nearest analogue we have in aerospace is creating Ground Test and Flight Test procedures.</p><p>Typically, when aerospace projects get pretty far along in their development processes, they go through Ground Test procedures that are designed as a way to validate that all these larger components actually work. It’s called “Ground Testing” because we can test them in a controlled environment where things are bolted down and secured to the ground. A great example of this is rocket “hot fire” tests, which is basically just a way to see that the (<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.reddit.com/r/rocketry/comments/4fvsm9/please_tell_me_why_rocket_engines_are_so_hard_to/">extremely complicated</a>) rocket engines actually do their job.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/watch?v=zi8RJlx6Eo4">https://www.youtube.com/watch?v=zi8RJlx6Eo4</a></p><p>For Crypto, what we can do to simulate a “Ground Test” of some component is performing larger-scale, agent-based simulations demonstrating that across a variety of different environments that the component functions as intended. A great example of a project doing this in practice is DelV’s (formally ElementFi’s) simulation framework for the next iteration of their protocol:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/delvtech/elf-simulations">https://github.com/delvtech/elf-simulations</a></p><p>Anyways, Ground Tests validate that as the project comes together, all the largest pieces are working as intended, which is really convenient to de-risk probably the scariest part of any aerospace project development: Flight Testing.</p><p>Flight Testing is scary because no matter how much simulation and testing we’ve done, there’s still no way to know for sure that it’s all going to work together. This is because often the full system simply isn’t capable of being tested in a controlled environment or in a truly “safe” way. The best we can do is try to limit the scope and envelope of our test flights so that we are achieving the key objectives we need to prove that the system is fully capable of the mission we designed it for.</p><p>Still, the worst case scenarios often happen, but we prepared for them since we knew from the start what the worst outcomes could be, and we have backups and contingencies for the failures that are possible (since we already did our analysis). This is the best way we can make sure our project pushes the envelope of what’s possible in the safest way we can, so scenarios like a rocket blowing up aren’t catastrophic to the project:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/watch?v=w0ZlFXoq4c0">https://www.youtube.com/watch?v=w0ZlFXoq4c0</a></p><p>For a Crypto project, what we can do is run a Beta launch or some sort of incentivized testnet, meant to uncover bugs, inefficiencies, and places where we misunderstood the problems we expected the project to face during the design phase. A good team will have designed out a roadmap of these tests all driving towards the final stage of the build process: actually launching the damn thing for everyone to use!</p><div class="relative header-and-anchor"><h2 id="h-conclusion">Conclusion</h2></div><p>I hope some of my insights from my prior career is helpful to you when thinking about how you can best design and build safe, secure, and successful projects that work well. I want to thank <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/danielvf">@danielvf</a> and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/0x_Osprey">@0x_Osprey</a> for reviewing this article and giving great feedback.</p><hr><p>For the latest on all things Ape follow us on: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://apeworx.io/">apeworx.io</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/invite/apeworx">Discord</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/ApeFramework">Twitter</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://staging.bsky.app/profile/apeworx.io">Bluesky</a></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/d79790215d94885973f0fcc10ac81055.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Cover Your Ass]]></title>
            <link>https://paragraph.com/@apeworx/cover-your-ass</link>
            <guid>bu8edjugx73UgwwyFUFm</guid>
            <pubDate>Fri, 21 Jul 2023 20:30:04 GMT</pubDate>
            <description><![CDATA[…or, what coverage is, and what it isn’tCode Coverage is a simple and (for some reason) controversial topic. Ask any group of developers, and you’re ...]]></description>
            <content:encoded><![CDATA[<p>…or, what coverage is, and what it isn’t</p><p>Code Coverage is a simple and (for some reason) controversial topic. Ask any group of developers, and you’re likely to get many conflicting opinions on how to do it properly. Some will say “well 100% or bust”, others will say it doesn’t matter at all. Some absolute crackpot (totally not me) may come at you with a line like “well actually, there’s between 7-13 different types of coverage, depending on how you measure it”, and what’s wild is that they would all be right. And also all are wrong. Each tell a version of the truth, because coverage is simultaneously a really important and powerful tool for increasing the safety and quality of code, as well as an absolutely useless measure of code safety and quality.</p><p>Confused? Good! Now let’s begin our journey!</p><p>p.s. this is Part 1 of our series on understanding code coverage. This piece will be an overview, while Part 2 will be practical using Ape Framework’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.apeworx.io/ape/stable/userguides/testing.html#contract-coverage">new coverage feature</a>. But more on that later.</p><div class="relative header-and-anchor"><h2 id="h-what-is-coverage-anyways">What is Coverage Anyways?</h2></div><p><strong><em>“Code coverage</em></strong>* is defined as a percentage measure of the degree to which the source code of a program is executed when a particular test suite is run.”* - <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://en.wikipedia.org/wiki/Code_coverage">Wikipedia</a>.</p><p>Uh, thanks Wikipedia. Very helpful.</p><p>So what does that mean? It means that when you create a test, there are particular areas of the code you&apos;re trying to verify that you are activating when you run it. It’s usually measured on a percentage basis, meaning if you have covered 80% of the entire source code then 80% has been activated while testing. Getting to 100% means you are activating the entire code in some way by running your tests. Is it the right way? Who knows, all it tells you is you got 100%. A perfect score. That’s all we care about. Our work is done. We are totally safe now.....</p><p>Right?</p><p>Annoyingly, the answer is no.</p><p>Code coverage metrics, as a percentage score, are really telling you very little about whether your code doing is the right thing, which is what we care about at the end of the day. The only thing that 80% coverage means is that 80% of the code did something during the test, not if it&apos;s what you wanted it to do or if it was done well.</p><p>To makes things even more confusing, most people only ever talk about &quot;statement coverage&quot;, which is just one of many types we can use (don&apos;t worry we&apos;ll get into them later).</p><p>Code coverage is imperfect, but useful and should be combined with other tests, fuzzing, and old-fashioned eyes-on-the-code to work through if your program is actually doing what you want it to. And whatever you do, always keep Goodhart&apos;s Law in mind:</p><p>“<em>When a measure becomes a target, it ceases to be a good measure.</em>” - C. Goodhart</p><div class="relative header-and-anchor"><h2 id="h-types-of-coverage">Types of Coverage</h2></div><p>Now, as the totally rational, sane person quoted in the beginning said (that’s totally not me), there are actually many different types of coverage we can use, so lets look into the the differences and what the shortcomings of each:</p><div class="relative header-and-anchor"><h3 id="h-statement-coverage">Statement Coverage</h3></div><p>Fundamentally, a particular coverage metric such as <em>statement coverage</em> measures the <em>hit rate</em> (aka the number of times a particular statement is hit) of a particular type of structure present in our code, such as a single statement in source code. </p><p>A <em>statement</em> is computer science jargon for an element of your program that expresses a complete “thought”, but just to keep things simple we are just going to think of it as a single line of source code.</p><p>Allow me to present a Python program as an example:</p><p><code>1 def function1(value: int) -&gt; int: 2 3 if value == 0: 4 value = 1 5 6 return value</code></p><p>This is a pretty simple program, but what happens if I told you that you could get 100% statement coverage with just one test? That’s pretty efficient right?</p><p>As I hope you can see, if we make the call with <code>value = 0</code>, we will actually be able to achieve 100% coverage of this code, since we will hit the <code>if</code> statement on line 3, the assignment statement on line 4, and the return statement on line 6. Of course, we’re calling <code>function1</code> so we will count that, and also we really don’t care about the whitespace on lines 2 and 5 (because they’re not actually programmatic statements).</p><div class="relative header-and-anchor"><h3 id="h-branch-coverage">Branch Coverage</h3></div><p>That’s great! But what are we missing? Well, we begin to see how 100% statement coverage might not be telling the whole story. Looking at the <code>if</code> statement on line 3 gives a clue: what if this condition were false? The statement coverage metric is that line 3 is just <em>hit</em>, it doesn’t specify anything about <em>how</em> it was hit. That concept is actually a different form of coverage called <em>branch coverage</em> (sometimes called <em>edge coverage</em>). Branch coverage checks that when we hit a statement that can cause a <em>branching point</em> in your code (literally a point where it has a binary choice to proceed down one path or another) that we trigger both the <em>positive</em> and <em>negative</em> scenario of this condition (e.g. <code>value == 0</code> and <code>value != 0</code>). Going back to our program, we only have one branch condition to measure, and we’ve only taken one of the branches in our test case of calling with <code>value = 0</code>, so this means we’ve only achieved 50% coverage of our branch conditions. Adding another test case where we call with <code>value = 1</code> will be enough to satisfy the other prong of that branch point by <em>not</em> triggering the condition, which will skip the <code>if</code> statement and proceed right to line 6.</p><p>Alright, let’s talk about a slightly more complicated example:</p><p><code>1 def function2(value: int) -&gt; int: 2 3 if value == 0 or value &gt; 10: 4 value = 1 5 6 return value</code></p><p>This time by executing both <code>value = 0</code> and <code>value = 1</code> test cases, we are able to achieve 100% statement coverage as well as 100% branch coverage too. However, I’m sure you’re able to see that the additional logic on our <code>if</code> statement might be cause for concern. But how? We have 100% coverage!</p><div class="relative header-and-anchor"><h3 id="h-condition-coverage">Condition Coverage</h3></div><p>Of course, the solution to any problem in computer science is that if your initial idea doesn’t work out, just add more abstraction. Clearly just checking that we proceeded down both paths of the branching <code>if</code> statement is not enough to fully exercise the logic of the condition inside of it. This may or may not be important to you depending on your needs, and indeed many coverage tools conveniently stop at statement and branch coverage.</p><p>But consider this: what if our understanding of <code>function2</code> was that it was supposed to be functionally identical to <code>function1</code>? By only checking our two test cases <code>value = 0</code> and <code>value = 1</code>, we would see that is indeed the case since they produce the same output. They would also produce the same output for <code>value</code> up to 10, and actually below 0 as well. But if we pass in <code>value = 11</code> all of a sudden the two functions will return different values.</p><p>That isn’t good. But how do we detect this with coverage?</p><p>Good question. First, let’s talk about the condition in our <code>if</code> statement. The condition is a compound expression involving <code>and</code>. In <code>function1</code> further above, we only had the expression <code>value == 0</code> to evaluate both true and false to achieve full branch coverage. Now we have two expressions: <code>value == 0</code> and <code>value &gt; 10</code>. With our two test cases we’ve made both expressions true at the same time, but we’ve only evaluated the first expression false once, and have never made the second expression change value to false. For the purposes of computing branch coverage, this is enough, since if one of the expressions of an <code>and</code> expression evaluates false, then the whole expression evaluates false. But if instead we look at a metric called condition coverage we need to look a little deeper into the branch statement and determine if it contains a compound expression, and if it is a compound expression we need to check that we’ve achieved the positive and negative cases for all of the sub-expressions. Before adding our <code>value = 11</code> test case, we would have had only 75% coverage of the <code>and</code> compound expression (positive and negative for <code>value == 0</code> but only positive for <code>value &gt; 10</code>).</p><p>Now we will have 100% coverage across 3 coverage metrics!</p><div class="relative header-and-anchor"><h2 id="h-other-types-of-coverage">Other Types of Coverage</h2></div><p>Of course branch, statement and condition coverage are only 3 examples of coverage that produce useful checks to ensure you’ve explored as many paths in your program as possible. There are other types of coverage to check for, but they can have diminishing returns vs. the amount of time you spend achieving 100% coverage on them. What’s more important is that you’ve exercised your code under both the <em>anticipated</em> scenarios that you expect your users to use, as well as all of the <em>edge cases</em> and <em>failure modes</em> that you want to protect your code against.</p><p>A good suggestion would be to design a test suite that covers all of the anticipated scenarios for your users that you want the code to function for, as well as checks the failure modes and edge cases that you <em>don’t</em> want the code to handle (by failing gracefully). Once you’ve done that, the next step would be to measure the coverage of this test suite and see where the gaps are. Those gaps are the key, because they show you places in your codebase where you are missing something: missing a test (perhaps not understanding a requirement or under-specification in your design document… you do have one, right anon?), or you made the code too complex (such that it has more edge cases than you expected), or otherwise made a mistake somewhere along the way.</p><p>But I promised to tell you more about other types of coverage, so here is a list (again, thanks <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://en.wikipedia.org/wiki/Code_coverage#Coverage_criteria">Wikipedia</a> for the categories):</p><ul><li><p>Function coverage - higher level, but basically have you called every function possible</p></li><li><p>Modified Condition/Decision Coverage (MC/DC) - you’ve checked each sub-expression in a compound branching point individually e.g. <code>if (a or b) and c)</code></p></li><li><p>Parameter Value Coverage - you’ve checked all possible input types that the function might be called with in practice (great use case for fuzzing since this is usually pretty hard)</p></li><li><p>Linear Code Sequence and Jump coverage - not only every if statement in your source code, but every type of branch condition that the final executable supports (for example in EVM programs, have you called the fallback method? triggered empty value checks? external call failures? etc.)</p></li><li><p>Path coverage - have you covered every possible path in the final executable? (often fairly low level for common usage, albeit more exhaustive)</p></li><li><p>Entry/Exit coverage - have you entered into every possible function and triggered every possible return statement in that function?</p></li><li><p>Loop coverage - have you checked all loops if it is possible to <code>break</code> early, or skip iteration entirely, as well as execute the full loop iterations without hitting the <code>break</code> condition, if one exists?</p></li><li><p>State coverage - have you explored all possible states that the program can take (in EVM programs often this isn’t possible without some form of Symbolic Execution, which is an exhaustive search of all possible states)</p></li><li><p>Data-flow coverage - has every variable been initialized and used?</p></li></ul><div class="relative header-and-anchor"><h2 id="h-using-coverage-tools-in-practice">Using Coverage Tools in Practice</h2></div><p>Now that we understand pretty well the taxonomy of different types of coverage criteria and how they work, it’s important to know how one <em>measures coverage</em> in practice. You might be thinking “why do I care?” but it’s important to understand this, as some ways of collecting coverage information <strong>actually change your program!</strong></p><p><em>Whoa there! That’s not cool! If the tool modifies my program, isn’t there danger that it could make it not match the production behavior?</em></p><p>Yes! That is a risk you are taking!</p><p>You see, some coverage tools will modify the program you are measuring coverage for by inserting variables in particular points in the program that check to see if they are hit or not. Usually these values don’t affect the execution of your program, but they can slow it down and have other performance effects. In EVM programs, where the execution cost of a program is actually one of the critical resources that gets tracked (e.g. <em>gas</em>), then even adding harmless variables incurs extra resource usage that could modify the state of the program, e.g. make it fail when it should be passing. Therefore, for measuring the coverage of EVM programs, <strong>it is recommended not to use these approaches</strong> as they will impact the correctness of the results.</p><p>Other tools, like <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ApeWorX/ape/pull/1423">Ape’s new coverage feature</a>, will instead take execution traces and post-process this data into the relevant coverage metrics (fortunately for EVM programs, this is a relatively easy thing to do).</p><p>In our next post, we’ll walk through in more detail how to use Ape’s coverage feature effectively when preparing your EVM-based contracts for production deployment.</p><p>For now though, I hope you found this article useful in understanding exactly what coverage is and how it works!</p><hr><p>For the latest on all things Ape follow us on: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://apeworx.io/">apeworx.io</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/invite/apeworx">Discord</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/ApeFramework">Twitter</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://staging.bsky.app/profile/apeworx.io">Bluesky</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="subscribe://">subscribe://</a></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
        </item>
        <item>
            <title><![CDATA[Introducing Silverback]]></title>
            <link>https://paragraph.com/@apeworx/introducing-silverback</link>
            <guid>dJjLznsUpgQMhdQE7YMv</guid>
            <pubDate>Fri, 30 Jun 2023 20:37:49 GMT</pubDate>
            <description><![CDATA[A Platform for Web3 BotsThe decentralized web is inexhaustibly and unrelentingly connected. It was designed to provide an open architecture to build ...]]></description>
            <content:encoded><![CDATA[<div class="relative header-and-anchor"><h2 id="h-a-platform-for-web3-bots">A Platform for Web3 Bots</h2></div><p>The decentralized web is inexhaustibly and unrelentingly connected. It was designed to provide an open architecture to build the next iteration of the internet, one that was more permanent, more accessible, and less discriminatory to its users. It has no concept of nationality, race, ethnicity, sex, class, gender, age, or political correctness. Hell, it has no concept of a “bedtime”.</p><p>At the core of this hyper-connected, decentralized new world are high-value full-stack applications, which use smart contracts at their core to enact self-executing rules and policies that guide complex economic decision-making outside of the blockchain’s sand-boxed execution environment. But smart contracts aren’t where we live. We live in the real world, and in the real world, we want things like nice interfaces that display up-to-date, relevant information. We want reliable automation for tasks we don’t have the time to watch or handle. We want to build rich, sophisticated applications leveraging these policies at the core to drive an entire ecosystem of economic behaviors.</p><p>We want to build great products.</p><div class="relative header-and-anchor"><h3 id="h-supporting-great-products">Supporting Great Products</h3></div><p>We recently launched cHaOSneT, our testnet-as-a-service (with a twist):</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/apeworx.eth/mIKYEt54RgNs7R12Np1vEyp8z5HuBKBdCjCWqrnNfe8">https://mirror.xyz/apeworx.eth/mIKYEt54RgNs7R12Np1vEyp8z5HuBKBdCjCWqrnNfe8</a></p><p>As with all great products, we needed great infrastructure to support it. This infrastructure would need to be robust in times of stress, safe from exogenous and indigenous security threats, and have a set of finely crafted rules that it would follow when you’re not there to guide it out of harm’s way.</p><p>Silverback is a fundamental part of what makes this product great, because it allows us to support deployments of large amounts of automated behavior which makes our chaosnets <em>feel</em> just like the real mainnet environment. It allows us to quickly and easily provision, monitor, and manage our deployments so we spend less time on maintenance and more time delivering new and innovative bots that automate the types of behavior our users want to see.</p><p>Without Silverback, we wouldn’t be able to scale up cHaOSneT to a world-class product. But what are the specific things it solves to make our engineers’ lives easier?</p><div class="relative header-and-anchor"><h3 id="h-reliable-and-robust-infrastructure">Reliable and Robust Infrastructure</h3></div><p>We aren’t all experts at infrastructure management or operations. Most of us want something that <em>Just Works</em> and don’t want to think about what’s running underneath. Containers? Message queues? Archive nodes? Websockets? I just want to write a simple script!</p><p>Here’s a Silverback bot that handles $USDC <code>Transfer</code> events:</p><p><code>from ape_tokens import tokens from silverback import SilverBackApp app = SilverBackApp() USDC = tokens[&quot;USDC&quot;] @app.on_(USDC.Transfer) def exec_event1(log): # Do something with `log.amount` ...</code></p><p>How simple is that? There’s no worrying about what node we’re running on, if we’re about to run out of API credits soon, what happens if we have an error in our code sometimes? It. Just. <em>Works</em>.</p><div class="relative header-and-anchor"><h3 id="h-safe-and-secure-private-keys">Safe and Secure Private Keys</h3></div><p>The secret to operating anything important at scale is to protect yourself from… yourself. Nowhere else in Crypto is this any more evident than private key management. You cannot go a single week without learning about how someone got hacked and lost their private key. Basically, it’s <em>not</em> something you want to fuck up.</p><p>Thanks to Ape’s extensible plugin architecture, we can provide a seamless experience for your bots using managed key infrastructure that’s way more solid and battle-tested than what most people would develop themselves. It also allows us to support many more advanced types of managed key services, that will be released alongside the full Silverback platform release. You no longer have to worry about your private keys leaking as these secrets will be encrypted at rest, and only accessible via dedicated account plugins that the platform provides.</p><p>And besides that, we’ve made it so damn easy to use:</p><p><code>from ape import chain, project from silverback import SilverBackApp app = SilverBackApp() @app.on_(chain.blocks) def exec_event1(block): # Deploy a `Token` contract every 1,000th block if block.number % 1000 == 0: app.signer.deploy(project.Token)</code></p><p>That was a major goal with the product, to make it as easy as possible to do the <em>safe</em> thing well, so it can be a product you can trust with 5, 6, 7 figures… or more.</p><div class="relative header-and-anchor"><h3 id="h-event-and-policy-driven-risk-management">Event- and Policy-Driven Risk Management</h3></div><p>It can be really stressful to trust so much with a robot. But what choice do you have? You have to sleep sometime, and the chain never sleeps. Thankfully, Silverback’s risk management engine is there for you.</p><p>Perhaps the most important thing when creating truly trustworthy automation is that you can trust it to follow the guardrails you give it when things don’t go the way you want them to. Silverback bots will generate a set of metrics that can be externally monitored for deviations which should trigger a shutdown of your bot, as well as let you define your own programmatic logic which should stop processing immediately and trigger your shutdown procedures:</p><p><code>from ape import chain from ape_tokens import tokens from silverback import SilverBackApp app = SilverBackApp() USDC = tokens[&quot;USDC&quot;] INITIAL_BALANCE = USDC.balanceOf(app.signer) @app.on_(chain.blocks) def exec_event1(block): ... if USDC.balanceOf(app.signer) &lt; INITIAL_BALANCE: # Trigger a shutdown, and raise an alarm raise CircuitBreaker(&quot;We&apos;ve lost too much money!&quot;)</code></p><p>Also, through the Silverback platform’s metrics and logging features, you will be able to monitor the performance of your bot in order to identify longer-term trends like gas usage, transaction failure rate, and more.</p><div class="relative header-and-anchor"><h2 id="h-where-is-silverback-today">Where Is Silverback Today?</h2></div><p>You might be thinking “This all sounds great, how can I sign up?” and unfortunately we are only at the beginning stages of this journey. Silverback is a very innovative platform, and cHaOSneT is the first large-scale use of that platform, so we are still finding a ton of things about how it works and what types of features it will need to be most useful for production use cases. Thankfully, chaosnets are a fairly low-risk way for us to identify any problems with this architecture in the short term, and will ironically be a great test bed for back-testing your own production bots before they’re ready for prime-time on mainnet.</p><p>However, that’s not to say we don’t have something for you today. Our community was extremely excited to learn more about how they can build their own bots, so we wanted to speed up the timeline of releasing our open source bot-building library and SDK for the Silverback platform. You can check it out here:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ApeWorX/silverback">https://github.com/ApeWorX/silverback</a></p><p>You can use the library <em>today</em> for building a bot and run it using <code>silverback run</code> against any network, yes even production (you degen you). But to take advantage of the full power of the Silverback platform, you will have to wait a few more months until we release more details on the design and features that the platform will launch with.</p><p>For now… good luck and good hunting.</p><p>- ApeWorX</p><p>For the latest on all things Ape follow us on: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://apeworx.io/">apeworx.io</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/invite/apeworx">Discord</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/ApeFramework">Twitter</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://staging.bsky.app/profile/apeworx.io">Bluesky</a></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
        </item>
        <item>
            <title><![CDATA[Introducing ApePay]]></title>
            <link>https://paragraph.com/@apeworx/introducing-apepay</link>
            <guid>hrOxEXoYtTIK2Dmeffmi</guid>
            <pubDate>Tue, 06 Jun 2023 02:43:38 GMT</pubDate>
            <description><![CDATA[Streaming Crypto Payments for Off-chain ServicesWhat’s this? Yet another streaming payments system?Yes, but we swear there’s a good reason we built a...]]></description>
            <content:encoded><![CDATA[<div class="relative header-and-anchor"><h2 id="h-streaming-crypto-payments-for-off-chain-services">Streaming Crypto Payments for Off-chain Services</h2></div><p>What’s this? Yet another streaming payments system?</p><p>Yes, but we swear there’s a good reason we built and open sourced a new one!</p><div class="relative header-and-anchor"><h3 id="h-why-a-new-protocol">Why A New Protocol?</h3></div><p>When building <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/apeworx.eth/mIKYEt54RgNs7R12Np1vEyp8z5HuBKBdCjCWqrnNfe8">cHaOSneT</a> we realized that we had a decision to make: did we want to go the Web 2.0 way and use traditional login and payment processing, or did we want to go full Crypto-native and try to build something new?</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/apeworx.eth/mIKYEt54RgNs7R12Np1vEyp8z5HuBKBdCjCWqrnNfe8">https://mirror.xyz/apeworx.eth/mIKYEt54RgNs7R12Np1vEyp8z5HuBKBdCjCWqrnNfe8</a></p><p>Of course, we decided to do the latter, but this meant researching Crypto-native login and payment solutions. Login was easy, we used <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://login.xyz">Sign-in with Ethereum</a>, but in researching streaming payments platforms we had some problems. All the options we researched either didn’t have the right UX for this use case, were upgradeable (which is poor for automated services as it could cause an outage… among other things), or were otherwise not making updates to the protocol anymore. So… we needed to build our own!</p><div class="relative header-and-anchor"><h3 id="h-what-makes-apepay-cool">What Makes ApePay Cool?</h3></div><p>ApePay is designed from the ground up for the needs of automated service provisioning performed off-chain, such as the types of services we are building at ApeWorX for our users. We needed a minimal payment protocol that was flexible enough to meet our needs, and yet safe for users by allowing them to withdraw at any time to stop using our services. An upgradeable protocol was immediately off-limits. Maybe it would have been useful but <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.coindesk.com/tech/2023/05/21/attacker-takes-over-tornado-cash-dao-with-vote-fraud-token-slumps-40/">it’s just not safe</a>, and we also wanted to open source this protocol, so allowing what might seem like a minor upgrade to the contracts could risk completely wrecking our infrastructure. Immutable protocols are the way to go for robust, scalable infrastructure since their behaviors won’t change on a whim.</p><p>That’s great, but here are some of the actual benefits of ApePay’s architecture:</p><ol><li><p>It’s extremely scalable!</p></li><li><p>it unlocks smart contract workflows for users</p></li><li><p>It can re-purposed for multiple different products</p></li></ol><p>We also added support for Permit2, and wrote it in gas-efficient Vyper v0.3.9!</p><p>But let’s dive a little deeper…</p><div class="relative header-and-anchor"><h3 id="h-apepay-is-scalable">ApePay is Scalable</h3></div><p>Since ApePay is a decentralized application, and not just another centralized payment service, downtime is effectively eliminated. We don’t have to host servers, or make relationships with credit card companies in 195 different global jurisdictions. Everything is just crypto, streamed at a defined rate, until it either runs out or is cancelled by the stream creator (or us).</p><p>Reliability makes it possible for us to build our product infrastructure around this protocol, and that’s exactly what we’re doing by leveraging the upcoming Silverback platform for managing the off-chain integrations behind each of our products. When you open an ApePay stream, our infrastructure will automatically detect this action, and then parse the stream to provide the services that you paid for, as transparently and quickly as possible.</p><p>What about spam? Chargebacks? Compliance?</p><p>Since each ApePay StreamManager contract is it’s own self-sovereign hub, the owner has complete control over how they handle streams and under what conditions users are allowed to set them up in the first place. By using an optimistic architecture - basically that you trust the hub owner enough to open a stream with them - we can eliminate a lot of the complexity of negotiating on-chain when errors do happen. Made a payment by mistake? Close the stream (after a pre-defined warm-up period design to protect against DDoS attacks against the infrastructure). The service was down? The owner can just credit you with more time than the stream specifies off-chain. Only want to allow certain users during a limited beta? Add validators contract to deny users who shouldn’t be allowed or don’t meet specific conditions.</p><p>All of these features are executed completely on-chain, and we can rely on this behavior to negotiate off-chain using the assumptions of the protocol. Very human, and easy to use!</p><div class="relative header-and-anchor"><h3 id="h-apepay-unlocks-smart-contract-workflows">ApePay Unlocks Smart Contract Workflows</h3></div><p>This was a cool one for us to realize, imagine this: what if you allowed a service user to be a smart contract that pays for it’s own usage? As an example, let’s say you are building an arbitrage bot that runs on the (upcoming) Silverback platform. You create a contract used to hold the assets at rest, and have that contract manage it’s own payment stream used to pay for running the bot directly from the profits! This is really cool, because you don’t have to worry about setting up those recurring payments, or what happens if your payment processor goes down, since it’s a decentralized application that’s always running the subscription as long as you want it to. What’s more, you can have the bot shut itself down if it’s no longer working profitably.</p><p>This is the future we’re asking for!</p><div class="relative header-and-anchor"><h3 id="h-apepay-can-be-repurposed-for-multiple-products">ApePay Can Be Repurposed For Multiple Products</h3></div><p>If we were gonna design our own payments protocol, we wanted to make sure it was flexible enough to support all our future products. Since ApePay is a very simple but very configurable system, we were confident that it can grow and scale to support whatever future products we (and the community!) might build with it. And by open sourcing it to our community, it’ll be interesting to see how others might evolve and adapt the rules of the protocol to create even more interesting use cases.</p><p>It’ll be especially interesting to see how ApePay will allow centrally viewing and managing payment streams across our product suite, and potentially from multiple service providers, all from a convenient dashboard (coming soon<em>™</em>)</p><div class="relative header-and-anchor"><h2 id="h-okay-how-can-i-learn-more">Okay, How Can I Learn More?</h2></div><p>ApePay is being open-sourced under <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ApeWorX/ApePay">this repository</a>, and maintained by ApeWorX. We accept feedback, contributions and feature requests, and will be integrating it with our <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://chaos.apeworx.io">cHaOSneT</a> product shortly. For now, there is no public deployment, but will be coming shortly, and of course anyone can deploy their own for testing purposes.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ApeWorX/ApePay">https://github.com/ApeWorX/ApePay</a></p><p><em>If you want to be one of the first to try out</em> cHaOSneT <em>just sign up to our Mirror email notifications to be given front row access for when we launch the Beta! Just sign up above and you’re in!</em></p><p>#PrepareForcHaOS</p><p>- ApeWorX</p><p>For the latest on all things Ape follow us on: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://apeworx.io/">apeworx.io</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/invite/apeworx">Discord</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/ApeFramework">Twitter</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://staging.bsky.app/profile/apeworx.io">Bluesky</a></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
        </item>
        <item>
            <title><![CDATA[Introducing ChaosNets: AI-Powered Testnets]]></title>
            <link>https://paragraph.com/@apeworx/introducing-chaosnets-ai-powered-testnets</link>
            <guid>liOTmYVoG8K7zeebhFsG</guid>
            <pubDate>Fri, 26 May 2023 22:42:38 GMT</pubDate>
            <description><![CDATA[Forget Testnets. Welcome to ChaosNetWe’re proud to release our latest product into a private alpha: ChaosNetFork any chain, at any time, and create v...]]></description>
            <content:encoded><![CDATA[<p>Forget Testnets. Welcome to ChaosNet</p><p>We’re proud to release our latest product into a private alpha: ChaosNet</p><p>Fork any chain, at any time, and create virtual humans to interact with it as if the chain was alive.</p><p>ChaosNet changes the way testnets work by giving you 100% real....fake people to let you see exactly how real people will interact with your project.</p><p><strong>The Three Core Powers of the Chaosnet AI:</strong></p><ul><li><p><strong>Replicants:</strong> Create Autonomous Actors who mimic human and non-human behaviour. Turn on developer God-Mode to see how people would actually use your project.</p></li><li><p><strong>Time-Travel:</strong> Select any block to go back in time and see what would happen if things went differently using the behaviour of the people who were there. Speed up, slow down, or view any chain activity and see whats happening as it happens.</p></li><li><p><strong>Simulacrum:</strong> Replicate events from other chains and simulate anything from USDC depegging, to Satoshi coming back, to a chain collapsing and see it play out in real time. Watch as a chain collapses, a fork splits, or a bridge is hacked without you getting rekt in the process.</p></li></ul><p>Simulate events, strategies, the past, the future, and users with the AI power of ChaosNet</p><p>If you want to be one of the first to try out ChaosNet just sign up to our Mirror email notifications to be given front row access for when we launch the ChaosNet Beta! Just sign up and you’re in!</p><p>#PrepareForCHaOS</p><p>- ApeWorX</p><p>For the latest on ChaosNet follow us on: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://apeworx.io/">Apeworx.io</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/invite/apeworx">Discord</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/ApeFramework">Twitter</a> | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://staging.bsky.app/profile/apeworx.io">Bluesky</a></p>]]></content:encoded>
            <author>apeworx@newsletter.paragraph.com (ApeWorX LTD)</author>
        </item>
    </channel>
</rss>