<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Aseneca</title>
    <description>The latest articles on Forem by Aseneca (@aseneca).</description>
    <link>https://forem.com/aseneca</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1202712%2Fcedc214c-1c63-4f3a-9fa2-189bab2536c5.jpg</url>
      <title>Forem: Aseneca</title>
      <link>https://forem.com/aseneca</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/aseneca"/>
    <language>en</language>
    <item>
      <title>Transaction Message Header: An ELI5 Into the Transaction Message Header Semantics</title>
      <dc:creator>Aseneca</dc:creator>
      <pubDate>Sun, 13 Apr 2025 13:39:08 +0000</pubDate>
      <link>https://forem.com/aseneca/transaction-message-header-an-eli5-into-the-transaction-message-header-semantics-4dpg</link>
      <guid>https://forem.com/aseneca/transaction-message-header-an-eli5-into-the-transaction-message-header-semantics-4dpg</guid>
      <description>&lt;p&gt;A transaction is a set of signatures of serialized messages signed by the first key of  the Message’s account key.&lt;/p&gt;

&lt;p&gt;The message in a transaction is a structure containing a &lt;code&gt;header&lt;/code&gt;, &lt;code&gt;account_keys&lt;/code&gt;, &lt;code&gt;recent_blockhash&lt;/code&gt; and &lt;code&gt;instructions&lt;/code&gt;. The header contains the &lt;code&gt;MessageHeader&lt;/code&gt; which describes the organization of the Message’s account keys. &lt;br&gt;
Every instruction specifies which accounts it may reference, or otherwise requires specific permissions of. Those specifications are: whether the account is read-only, or read-write; and whether the account must have signed the transaction containing the instruction.&lt;/p&gt;

&lt;p&gt;Whereas individual Instructions contain a list of all accounts they may access, along with their required permissions, a Message contains a single shared flat list of all accounts required by all instructions in a transaction. When building a Message, this flat list is created and Instructions are converted to a set of &lt;code&gt;CompiledInstructions&lt;/code&gt;. Those &lt;code&gt;CompiledInstructions&lt;/code&gt; are then reference by index the accounts they require in the single shared account list.&lt;/p&gt;

&lt;p&gt;The shared account list is ordered by the permissions required of the accounts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;accounts that are writable and signers&lt;/li&gt;
&lt;li&gt;accounts that are read-only and signers&lt;/li&gt;
&lt;li&gt;accounts that are writable and not signers&lt;/li&gt;
&lt;li&gt;accounts that are read-only and not signers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given this ordering, the fields of MessageHeader describe which accounts in a transaction require which permissions.&lt;/p&gt;

&lt;p&gt;When multiple transactions access the same read-only accounts, the runtime may process them in parallel, in a single PoH entry. Transactions that access the same read-write accounts are processed sequentially.&lt;/p&gt;

&lt;h2&gt;
  
  
  Message Header
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;MessageHeader&lt;/code&gt; describes the organization of a transaction Message’s account keys. It’s structure is defined as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pub struct MessageHeader {&lt;br&gt;
    pub num_required_signatures: u8,&lt;br&gt;
    pub num_readonly_signed_accounts: u8,&lt;br&gt;
    pub num_readonly_unsigned_accounts: u8,&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Where  &lt;code&gt;num_required_signatures&lt;/code&gt; represents the number of signatures required for this message to be  valid, &lt;code&gt;num_readonly_signed_accounts&lt;/code&gt; represents the last &lt;strong&gt;num_readonly_signed_accounts&lt;/strong&gt; that are read-only signers, while &lt;code&gt;num_readonly_unsigned_accounts&lt;/code&gt; represents the last &lt;strong&gt;num_readonly_unsigned_accounts&lt;/strong&gt; that are read-only non-signers..&lt;/p&gt;

&lt;p&gt;By reading these three values in the &lt;code&gt;MessageHeader&lt;/code&gt; and the &lt;code&gt;account_keys&lt;/code&gt; array in the Message, the runtime can by index, deterministically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Know which accounts are signer vs non-signers&lt;/li&gt;
&lt;li&gt;Know which accounts are read-only vs writable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now consider a reverse scenario where instead of the number of read-only signatures, we have a number of writable signers? That is, simply flipping the logic to define the &lt;code&gt;MessageHeader&lt;/code&gt; like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pub struct FlippedMessageHeader {&lt;br&gt;
    pub num_required_signatures: u8,&lt;br&gt;
    pub num_writable_signed_accounts: u8,&lt;br&gt;
    pub num_writable_unsigned_accounts: u8,&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This would also work in theory but compared to the original design has some performance implications. &lt;/p&gt;

&lt;p&gt;From the flipped logic of message header, the runtime would have to infer a couple of things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first num_writable_signed_accounts in account_keys[0..num_required_signatures] are writable.&lt;/li&gt;
&lt;li&gt;The rest are read-only signers.&lt;/li&gt;
&lt;li&gt;The first num_writable_unsigned_accounts in the rest are writable non-signers.&lt;/li&gt;
&lt;li&gt;The rest are read-only non-signers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However with this approach, we lose the &lt;strong&gt;suffix parsing&lt;/strong&gt; behavior in the original design.&lt;/p&gt;

&lt;p&gt;With the original design, Read-only accounts are at the end of their respective signer/non-signer group which makes range slicing easy:&lt;br&gt;
&lt;code&gt;account_keys[0..n] -&amp;gt; all signers&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;account_keys[n..] -&amp;gt; all non-signers&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Within each, the tail can be used to mark "read-onlys"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With flipped logic:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Writable accounts are at the front, so we would need to slice the beginning of each group and then infer "read-onlys" as a suffix after skipping "writables" (prefix-based parsing). &lt;/p&gt;

&lt;p&gt;Consider this analogy further. Say we have &lt;code&gt;account_keys=  [A, B, C, D, E, F]&lt;/code&gt;, and the header:&lt;br&gt;
&lt;code&gt;num_required_signatures = 3&lt;br&gt;
num_readonly_signed_accounts = 1&lt;br&gt;
num_readonly_unsigned_accounts = 1&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
From this example, &lt;br&gt;
Signers: &lt;code&gt;[A, B, C]&lt;/code&gt;&lt;br&gt;
Last one of them (C) -&amp;gt; read-only signer&lt;br&gt;
First two of them (A, B) -&amp;gt; writable signers&lt;/p&gt;

&lt;p&gt;Non-signers: &lt;code&gt;[D, E, F]&lt;/code&gt;&lt;br&gt;
Last one of them (F) -&amp;gt; read-only non-signer&lt;br&gt;
First two of them (D, E) -&amp;gt; writable non-signers&lt;/p&gt;

&lt;p&gt;Slicing can be done cleanly and easily based on suffix counts like this:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
writable_signers = account_keys[0..(3 - 1)] = [A, B]&lt;br&gt;
readonly_signers = account_keys[(3 - 1)..3] = [C]&lt;br&gt;
writable_non_signers = account_keys[3..(6 - 1)] = [D, E]&lt;br&gt;
readonly_non_signers = account_keys[5..6] = [F]&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now if we go along with the flipped logic and assume the header stored:&lt;br&gt;
&lt;code&gt;num_required_signatures = 3&lt;br&gt;
num_writable_signed_accounts = 2&lt;br&gt;
num_writable_unsigned_accounts = 2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To find read-onlys, now we have to compute:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
First two in the signer section -&amp;gt; writable&lt;br&gt;
The rest -&amp;gt; read-only&lt;br&gt;
First two in the non-signer section -&amp;gt; writable&lt;br&gt;
The rest -&amp;gt; read-only&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
So for read-only accounts, you have to offset forward rather than slice from the end.&lt;/p&gt;

&lt;p&gt;This means we  can’t just slice_from_end(count) anymore and we now need to compute and track forward ranges like:&lt;br&gt;
&lt;code&gt;readonly_signers = account_keys[num_writable_signed_accounts..num_required_signatures]&lt;/code&gt;&lt;br&gt;
Which gets more awkward if counts don’t line up cleanly or if you add more categories.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;While it is quite semantically logical to flip the logic in theory, in practice there would be some performance trade-off to that effect. By assuming "writability" by default and counting only the exception, the runtime not only minimizes bytes encoding but also encourages a compact, fast, suffix-parsed, position based inference. &lt;br&gt;
Also with suffix-based parsing (read-only last), we can just slice from the end which is much simpler and cleaner that prefix-based parsing (writable first) where we would need to offset forward which is more difficult.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://www.anza.xyz" rel="noopener noreferrer"&gt;www.anza.xyz&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dl.acm.org/doi/pdf/10.1145/233551.233555" rel="noopener noreferrer"&gt;https://dl.acm.org/doi/pdf/10.1145/233551.233555&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Ironforge: A Comprehensive DevOps Platform for Web3 Applications</title>
      <dc:creator>Aseneca</dc:creator>
      <pubDate>Mon, 02 Dec 2024 14:47:34 +0000</pubDate>
      <link>https://forem.com/aseneca/introduction-to-ironforge-a-comprehensive-devops-platform-for-web3-applications-51cj</link>
      <guid>https://forem.com/aseneca/introduction-to-ironforge-a-comprehensive-devops-platform-for-web3-applications-51cj</guid>
      <description>&lt;p&gt;As the web3 development space accelerates at incredible pace towards achieving decentralization, increased bandwidth and reduced latency, an important need that arises is core infrastructure support enabling developers to improve development lifecycle, integration and reliability while ensuring continuous performance observability. This is the focus of Ironforge team- to provide the best RPC Orchestration and Observability platform in web3.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Ironforge?
&lt;/h2&gt;

&lt;p&gt;Ironforge is the leading DevOps platform on Solana, offering serverless infrastructure for developers. Ironforge aims to equip Web3 developers with tools that enable them focus on building while providing infrastructure management through solutions such as observability, incident management, networking, security enterprise solutions such as automation, streamlined organization and project management. Ironforge is trusted and used by most large-scale teams including Jupiter, Kamino Finance, Switchboard, Solflare, Orca, Bonk and many others. It is also streamlined to serve individual developers as well, and provide a dynamic and interactive UI/UX. &lt;br&gt;
With Ironforge, individual developers and teams can become more efficient by simplifying application development, truncate overhead in project organization process, and avoid complexities of redundant tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;p&gt;Ironforge provides efficient DevOps operations by offering several unique features:&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced Intelligent RPC Routing and Management
&lt;/h3&gt;

&lt;p&gt;Ironforge offers two distinct Routing methods &lt;strong&gt;Primary and Dynamic Routing Methods&lt;/strong&gt; to tailor application’s RPC requests to its specific needs. With Ironforge, projects can analyze application’s behaviour, identity issues and optimize performance within a single platform.&lt;br&gt;
&lt;strong&gt;Primary Routing&lt;/strong&gt; is the default routing strategy for all RPC methods while &lt;strong&gt;Dynamic Routing&lt;/strong&gt; gives developers more customizable options to assign specific endpoints for specific RPC methods therefore enabling them control how requests are routed based on the RPC method. Ironforge also provides dedicated RPC endpoints monitoring for each RPC endpoint, equipping developers with real-time transaction slot latency data to make fast informed decisions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpc1f7r7qdcm6ebp8fzhn.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpc1f7r7qdcm6ebp8fzhn.jpeg" alt=" " width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Alerts
&lt;/h3&gt;

&lt;p&gt;Ironforge provides a real-time monitoring system, enables developers to set up alerts to monitor specific application health and performance metrics and receive quick feedback through notifications when issues arise. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4g1l35d5xtcgbzsyuix.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4g1l35d5xtcgbzsyuix.jpeg" alt=" " width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  In-depth Application Observability
&lt;/h3&gt;

&lt;p&gt;Developers need analytics and logs data to understand applications dynamic behavior and potential. Ironforge aims to provide native SAS (Statistical Analysis System) tooling for web3 application performance monitoring to provide comprehensive advanced analytics, business intelligence, data management, predictive analysis and logs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Load Balancers
&lt;/h3&gt;

&lt;p&gt;Ironforge Load Balancers enable developers to efficiently distribute RPC requests across multiple Solana endpoints. Developers can configure multiple RPC endpoints and select load balancing algorithms and routing strategies that are apt for their application needs. This feature provides two routing strategies, Primary and Dynamic, which allows developers to specifically configure the route of every RPC method call, giving them more autonomy over how requests are distributed across RPC endpoints. &lt;br&gt;
With each routing strategy developers can set up load balancing algorithms such as &lt;strong&gt;Sequential&lt;/strong&gt; and &lt;strong&gt;Parallel&lt;/strong&gt; algorithms for RPC endpoints.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Sequential Load Balancing Algorithm
&lt;/h4&gt;

&lt;p&gt;In the sequential load balancing algorithm, Ironforge forwards requests to the first available RPC endpoint in the configured list. If that endpoint responds successfully, it is used. If for some reason that endpoint is unavailable or returns an error, the request is forwarded to the next available endpoint in the sequence and so on until a successful response is obtained or all endpoints have been attempted. Developers have control over the sequence of endpoints through which the requests should be processed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Parallel Load Balancing Algorithm
&lt;/h4&gt;

&lt;p&gt;This algorithm enables Ironforge to send requests simultaneously to all available endpoints and uses the response from the first endpoint that responds successfully, while discarding the responses from the other endpoints. With this algorithm, developers can utilize the power of a parallel processing structure to reduce response time and maximize performance but there is a &lt;strong&gt;tradeoff&lt;/strong&gt; for less customization control and flexibility. Also, the parallel load balancing algorithm may incur higher costs whenever there is increased utilization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Firewall Rules
&lt;/h3&gt;

&lt;p&gt;Ironforge ensures developers can focus on building without worrying about application security. It does this through its &lt;strong&gt;Firewall Rules&lt;/strong&gt; feature which provide benefits such as rate limiting, IP and domain whitelisting, RPC method blocking and more. The Firewall feature allows developers to define a set of conditions that must be met before a request is allowed to reach an RPC endpoint. These rules(which are setup with conditions) as well as the actions to take if the conditions are met, can be configured to meet the developers specific needs.&lt;br&gt;
The Firewall feature can be configured in two different ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Default mode:&lt;/strong&gt; All requests are allowed by default and developers can create rules to block specific requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firewall Mode:&lt;/strong&gt; This is the inverse of the default mode. In this mode, all requests are blocked by default and developers can create rules to allow specific requests.
Firewall rules consist of conditions that must be met before a specific action is taken. Ironforge provides great levels of customization and conditions for Firewalls, allowing developers to create complex rules that meet their requirements. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comprehensive Transaction Observability
&lt;/h3&gt;

&lt;p&gt;Ironforge enables developers to gain deeper insight on transaction landing rates, transaction latency,  CU units and pricing, priority fees, transaction confirmation rates, transaction drop rates, error logs on transactions. It provides detailed analytics, metrics, logs and comprehensive reports on transactions which is useful in monitoring and identifying issues with transactions and provide insights on how developers can improve transaction success rate and save money by optimizing transactions. &lt;/p&gt;

&lt;h3&gt;
  
  
  Highly Intuitive UI/UX
&lt;/h3&gt;

&lt;p&gt;Ironforge also implements a very intuitive UI/UX and interactive dashboard to streamline the user experience. Aside from these highly interactive and visualized dashboards for managing and monitoring features such as Alerts, Firewalls, Load balancer and much more, it also provides an interactive timeline view for monitoring and analyzing events in real-time. This feature enables developers to effectively manage systems by visualizing and filtering real-time event data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvayrss6qdipl5k8h9yv8.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvayrss6qdipl5k8h9yv8.jpeg" alt=" " width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prominent Use Cases and Impact
&lt;/h2&gt;

&lt;p&gt;Being the leading DevOps operation platform on Solana, Ironforge is suitable for projects ranging from small dApps to enterprise-level platforms. It is trusted by many large-scale teams to enhance scalability, reliability and security of their applications. Some of the prominent use cases and impact include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Load balancing and failover capabilities:&lt;/strong&gt; distribute requests across multiple RPC providers therefore minimizing downtime and maximizing throughput. By rerouting traffic through intelligent strategies during outages and congestion, Ironforge ensures high transaction success rates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Transaction Management and Observability:&lt;/strong&gt; retry mechanisms, state confirmations and low-latency execution ensure fast and consistent transaction processing. With the Ironforge transaction observability module, projects can gain insights into how much transactions are costing them and how much they can save if CU units and pricing are optimized.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7nl6ndyelk3epy4v5vji.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7nl6ndyelk3epy4v5vji.jpeg" alt=" " width="800" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Observability, Monitoring and Real-time Analytics:&lt;/strong&gt; Utilizing intuitive UI/UX, interactive dashboards and sas tooling, Ironforge provides insights into RPC performance, application’s health, transaction patterns, network health and other critical metrics for proactively scaling and maintaining dApps, identifying issues, optimizing performance and making informed decisions. It also provides customizable alerts for real-time events which can be integrate with tools like Slack, Discord or PagerDuty.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Robust Security:&lt;/strong&gt; Ironforge provide teams with customizable options to enhance their security requirements through firewall rules. Projects can whitelist domains, IP addresses for safer access and block unnecessary Solana RPC methods to improve performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Severless Solana Development:&lt;/strong&gt; manage and facilitate backend integrations, therefore enabling developers to focus on building rather than infrastructure management. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The numerous benefits that Ironforge provides cannot be understated. With Ironforge, projects can easily separate permission escalation for DevOps without being distracted from focusing on their core application’s logic. &lt;br&gt;
There has been a lot of releases this year that makes Ironforge standout as  a leading devOps platform for builders on Solana, but next year promises to be even more productive and efficient with the 2025 roadmap hinting to more improved log experience, more load balancer weighted algorithms and AI/LLM integration for more improved observability and business intelligence. If scaling your project’s infrastructure and security is crucial to you, then Ironforge is your best bet. The team is fast and responsive, they are always shipping, and they are strongly aligned with their core values to deliver an improved DevX.  To get started, visit &lt;a href="https://www.ironforge.cloud/" rel="noopener noreferrer"&gt;https://www.ironforge.cloud/&lt;/a&gt;, sign up, join the discord channel for 24/7 developer support and read the guides on &lt;a href="https://www.ironforge.cloud/guides" rel="noopener noreferrer"&gt;https://www.ironforge.cloud/guides&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Additional resources:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.ironforge.cloud/docs" rel="noopener noreferrer"&gt;Ironforge documentation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/ironforge-cloud" rel="noopener noreferrer"&gt;Ironforge repository&lt;/a&gt;&lt;br&gt;
&lt;a href="https://x.com/IronforgeCloud" rel="noopener noreferrer"&gt;Ironforge Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>solana</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>A Developer’s Guide into Account Abstraction Models</title>
      <dc:creator>Aseneca</dc:creator>
      <pubDate>Sat, 30 Nov 2024 22:17:50 +0000</pubDate>
      <link>https://forem.com/aseneca/a-developers-guide-into-account-abstraction-models-1jl1</link>
      <guid>https://forem.com/aseneca/a-developers-guide-into-account-abstraction-models-1jl1</guid>
      <description>&lt;p&gt;One of the core factors that has contributed to the influx of new users to crypto and usage of crypto wallets is accounts abstraction (AA). While continuous developments are being made around this concept, the idea of &lt;a href="https://blog.ethereum.org/2015/07/05/on-abstraction" rel="noopener noreferrer"&gt;account abstraction&lt;/a&gt; was first proposed by Vitalik Buterin, founder of Ethereum, in 2015. Its fundamental proposition was to move crypto from the current approach of EOA accounts (which are accounts that are externally owned and controlled by private keys) to a model where accounts can be customised depending on their application and are controlled by smart contracts.&lt;/p&gt;

&lt;p&gt;This article assumes the reader has no prior knowledge of AA models and aims to introduce the general concept AA by exploring its implementation in two prominent blockchains, namely Ethereum and Solana. By discussing their differences and the unique advantages each chain derives from the implementation of AA models at the core of their account structures, readers will better understand how these implementations can be adjusted to suit various needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an Account
&lt;/h2&gt;

&lt;p&gt;It is a general misconception among most crypto users that the term “account” refers to a wallet. This assumption however cannot be further from the truth. As a developer, it is important to note that an account is not a wallet. A wallet is simply an application that acts as gateways to interact with blockchain. So what then is an account?&lt;/p&gt;

&lt;h3&gt;
  
  
  Accounts on Ethereum
&lt;/h3&gt;

&lt;p&gt;In &lt;strong&gt;Ethereum&lt;/strong&gt;, accounts are basically “objects” that constitute the state of the blockchain. These objects consist of a 20-byte address, and state transitions within the blockchain are as a result of transfer of value and information between these accounts. An Ethereum account contains four fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;nonce&lt;/strong&gt;, a counter that tracks processed transactions&lt;/li&gt;
&lt;li&gt;The account’s current &lt;strong&gt;ether balance (ETH)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The account’s &lt;strong&gt;contract code-hash&lt;/strong&gt; which is the hash of the EVM code of the contract. The contract is immutable but its state is mutable (For EOAs, this is a hash of an empty string since EOAs do not store code)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage,&lt;/strong&gt; an encoding of the state of the account
In Ethereum, there are two types of accounts: &lt;strong&gt;externally owned accounts&lt;/strong&gt;(EOA) which are controlled by private keys, and &lt;strong&gt;contract accounts&lt;/strong&gt;, which are controlled by their contract code. EOAs do not store code and transmit information only by creating and signing transactions. Contract accounts on the other hand store code which activates whenever that account receives a message, therefore enabling it to read and write to internal storage and send messages or create contracts (contracts on Ethereum can be analogous to “agents” within the EVM that executes a piece of code as instructed by a transaction or message. They have direct control over their own ETH balance and their own key/value store to keep track of persistent variables).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2gw151hkx3da3ip0nhu3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2gw151hkx3da3ip0nhu3.jpeg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;em&gt;(source: Helius.dev)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Accounts on Solana
&lt;/h3&gt;

&lt;p&gt;On Solana, accounts are more like storage which is capable of holding every type of data ranging from tokens to a program’s state variables such as integers, publickeys and even entire programs. The Solana account model requires that every account has an owner, and multiple accounts can have a single owner.&lt;br&gt;
A good analogy of the account model on Solana is a computer filesystem where a computer file can reference multiple data and state variables such as name, address, email e.t.c. Comparatively, in Solana, public keys can be likened to reference storage of state and data such as lamport, owner, rent, and executable.&lt;br&gt;
Similar to Ethereum, Solana accounts are of two main types: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Executable,&lt;/strong&gt; which consist of immutable programs that own and create other accounts that store state, &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-executable,&lt;/strong&gt; which are “storage or data” accounts that contain all other types of data like program variables, token balances, NFTs, etc. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Executable accounts&lt;/strong&gt; can further be delineated into &lt;strong&gt;Program Accounts,&lt;/strong&gt; which are accounts that store user-customised executable programs, and &lt;strong&gt;Native Program Account,&lt;/strong&gt; which store core native programs such as the &lt;strong&gt;System Program&lt;/strong&gt; which is responsible for the creation of accounts.&lt;br&gt;
Through executable accounts, instructions can be communicated to the network on how to execute transactions and through non-executable accounts, data can be stored (without the ability to execute code.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcab1ifznwqr2x683wfs.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcab1ifznwqr2x683wfs.jpeg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;em&gt;(source: Helius.dev)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The image above describes examples of executable and non-executable accounts. &lt;strong&gt;Bubblegum&lt;/strong&gt; is an example of a &lt;strong&gt;Program Account&lt;/strong&gt; by Metaplex used to create and manage compressed NFTs. &lt;strong&gt;Vote Program&lt;/strong&gt; is a &lt;strong&gt;Native Program Account&lt;/strong&gt; used to create and manage accounts that keep track of voting states. &lt;strong&gt;Associated Token Account&lt;/strong&gt;, &lt;strong&gt;System Account&lt;/strong&gt; and &lt;strong&gt;Stake Account&lt;/strong&gt; are all non-executable accounts that store some form of data. &lt;strong&gt;Associated Token Account&lt;/strong&gt; refers to accounts that hold data associated with a particular token, its balance and its owner (for example, 6ysptGHvXxPUs7T6jV5MGq157VUCUdreXQspt3w36EJF holds 10 USDC). Stake Account is used to stake/delegate token to validators and earn rewards.&lt;/p&gt;

&lt;p&gt;Accounts on Solana follow a specified structure defined by the &lt;em&gt;AccountInfo&lt;/em&gt; struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
pub struct AccountInfo&amp;lt;'a&amp;gt; {
    pub key: &amp;amp;'a Pubkey,
    pub lamports: Rc&amp;gt;,
    pub data: Rc&amp;gt;,
    pub owner: &amp;amp;'a Pubkey,
    pub rent_epoch: Epoch,
    pub is_signer: bool,
    pub is_writable: bool,
    pub executable: bool,
} 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;AccountInfo&lt;/strong&gt; struct holds the following fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;key,&lt;/strong&gt; which is a unique 32-byte public key by which accounts are identified&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;lamports,&lt;/strong&gt; which specifies the number of lamports owned by the account. Lamport is the unit of SOL which is the native token of Solana, and one lamport is one-billionth of one SOL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;data&lt;/strong&gt; is a reference to a raw data byte array that is stored by the account. It can be modified by programs and can store anything
The field owner specifies the owner of the account represented by the address of a program account &lt;strong&gt;(PubKey)&lt;/strong&gt;. A few rules guide account ownership on Solana:

&lt;ul&gt;
&lt;li&gt;Only an account owner can alter its state and withdraw lamport&lt;/li&gt;
&lt;li&gt;Anyone can deposit lamports into an account&lt;/li&gt;
&lt;li&gt;The owner of an account can reassign ownership to a new owner provided the account data is reset to zero&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;is_signer&lt;/strong&gt; is a boolean that indicates if a transaction has been signed by the owner of the account- this means that the account holds the private key that corresponds to the public key and has the authority to approve transactions&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;is_writable&lt;/strong&gt; field is a boolean which signifies whether an account state can be modified.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;executable&lt;/strong&gt; is a boolean that indicates whether an account is an executable or non-executable account.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;rent_epoch&lt;/strong&gt; refers to the next epoch at which an account will owe rent.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Account Abstraction Models
&lt;/h3&gt;

&lt;p&gt;Account abstraction is quite a broad concept, but narrowing it down, Account abstraction models simply aim to describe the process of abstracting away the rigid and built-in structures of accounts within a blockchain, therefore allowing them to be more flexible and adaptable. Its models hide the core technology of the user accounts from the users, enabling a more rich and less technical experience.&lt;br&gt;
Developers can utilise AA models to create customised and fluid user-friendly on-chain accounts where they can define their own custom logic for storing assets and executing transactions over the network.&lt;br&gt;
Through AA models, developers can create smart contracts (called programs on Solana) that can take up roles as customised user accounts and interact with other accounts, as well as execute composable program interactions.&lt;br&gt;
The advantages of AA models have far more crucial consequences on how users interact with programs and contracts on-chain by enabling implementation of custom execution logic while eliminating the need for a rigid set structure and giving developers the leeway to tailor user account structures to their specific needs.  To gain further understanding of  why AA models crucial for the next phase of development in blockchain, we shall examine their implementation within Ethereum and Solana.&lt;/p&gt;

&lt;h3&gt;
  
  
  Account Abstraction in Ethereum
&lt;/h3&gt;

&lt;p&gt;Until recently, account structures have been very rigid in Ethereum, leaving no room for developers to create and implement custom user accounts, therefore leading to poor user experience in storing and managing assets on-chain. This is why most popular Ethereum wallets such as Metamask only give users the option of creating EOA accounts, which means limited customization and flexibility since these accounts are controlled by private keys and can only be used to store data (ETH, ERC-20) and interact with smart contracts only by signing transactions.&lt;br&gt;
With the advent of ERC-4337 merged a novel account structure on EVM called Contract Accounts which was an improvement on EOA by introducing account abstraction- its implementation gave developers on Ethereum more possibilities through smart contracts that stores data, and code. Therefore eliminating the rigidity that came with accounts that are solely controlled by private keys, replacing it with functionality that is determined by the code within the smart contracts. The role that EIP- 4337 which eventually became the ERC-4337 standard played in the implementation of account abstraction on Ethereum will be discussed in another article.&lt;/p&gt;

&lt;h3&gt;
  
  
  Account Abstraction in Solana
&lt;/h3&gt;

&lt;p&gt;Solana blockchain since its inception has always implemented account abstraction at its core, therefore rendering accounts on Solana more flexible and simplifying the engineering of complex interactions between accounts and programs (programs are smart contracts on Solana).&lt;br&gt;
The account model on solana embraces separation of concerns at its core. Non-executable accounts (data accounts) storing data. They share some similarities with Ethereum EOA- both types of accounts are mainly used to hold and manage tokens, and interact with decentralised applications and smart contacts. Transactions can also be signed only by use of a private key on both types of accounts.&lt;br&gt;
With Solana however, programs can actually create and manage specific accounts by extending AA implementation through a feature called &lt;a href="https://dev.to/aseneca/cross-program-invocations-and-pdas-the-combination-of-two-powerful-mechanism-on-anchor-4b93"&gt;Program Derived Addresses&lt;/a&gt; (PDAs) therefore extending developers ability to define custom logic for managing these accounts. With PDAs, there can be flexibility in rules that govern how transactions are signed by authorising programs to execute various operations on-chain on behalf of the PDA in a way that does not require the need for private keys. Therefore abstracting the burden placed on users to manage actions without the use of private keys such as storage and management of SPL assets, batched transactions and multi-signature (multi-sig) account management features. PDAs also extend the functionality of accounts by enabling them to interact and manage executable accounts within one another; a feature known as &lt;a href="https://dev.to/aseneca/cross-program-invocations-and-pdas-the-combination-of-two-powerful-mechanism-on-anchor-4b93"&gt;Cross-Program Invocation&lt;/a&gt; (CPI).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Despite the difference in the implementations of AA models within these two popular chains, we can see that the benefits of AA are tremendous and hold lots of possibilities for what developers can accomplish. On Ethereum, implementations of AA models still remains an ongoing area of research and development as a result of its more rigid account structure at its core, while it is more obvious in Solana as a result of its flexible account models enabling complex interaction between account layers. One of the core use cases for AA models  is the implementation of smart wallets which is anticipated to onboard the next generation of crypto users due to their advanced features such as social account recovery, permissionless asset management and other benefits.&lt;br&gt;
However, presently implementation of AA models also has some challenges such as restraint in limitation of program composability by not exposing an IDL interface, a practice typically referred to as security through obscurity.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;References/Further resources&lt;br&gt;
Solana docs&lt;br&gt;
Ethereum Organization&lt;br&gt;
Vitalik Buterin, On Abstraction, &lt;a href="https://blog.ethereum.org/2015/07/05/on-abstraction" rel="noopener noreferrer"&gt;https://blog.ethereum.org/2015/07/05/on-abstraction&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developers.metaplex.com/bubblegum" rel="noopener noreferrer"&gt;https://developers.metaplex.com/bubblegum&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>solana</category>
      <category>blockchain</category>
      <category>web3</category>
      <category>ethereum</category>
    </item>
    <item>
      <title>Improving IDLs Discoverability: Accelerating Solana Development, Integration and Composability</title>
      <dc:creator>Aseneca</dc:creator>
      <pubDate>Mon, 11 Nov 2024 10:50:51 +0000</pubDate>
      <link>https://forem.com/aseneca/improving-idls-discoverability-accelerating-solana-development-integration-and-composability-4oae</link>
      <guid>https://forem.com/aseneca/improving-idls-discoverability-accelerating-solana-development-integration-and-composability-4oae</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Solana has garnered the reputation as the fastest and most scalable blockchain on the the market, leveraging its unique architecture to achieve high throughput and low latency. However, associated with a massive growth of this scale, is an important component of the ecosystem that requires constant attention: &lt;strong&gt;Developer Experience (DX)&lt;/strong&gt;. Improving the developer experience is always in the spotlight as developers and builders are the lifeline of Solana. &lt;br&gt;
IDLs discovery and implementation for existing infrastructure appears to be a problem many developers in Solana presently struggle with. Two main concerns are predominantly echoed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reading data&lt;/strong&gt; on the network is difficult and even more so for non-anchor programs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Obscurity in CPI&lt;/strong&gt; with programs as security concerns &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, we will explore what Interface Definition Language (IDL) is all about, and how they are a vital part of improving the development experience on Solana. This article aims to provide a comprehensive understanding of the role IDLs play across the Solana development landscape, and why further understanding into upgrading its discoverability will bolster and accelerate development experience on Solana.&lt;/p&gt;
&lt;h3&gt;
  
  
  Interface Description Language(IDL)
&lt;/h3&gt;

&lt;p&gt;An Interface Definition Language (IDL) in Solana refers to the public interface of a program. It represents the structure of programs accounts, instructions as well as error codes. They are usually in a JSON and Typescript file format and they are used to generate client-side code enabling clients to easily interact with a Solana program. They are automatically generated for programs written in anchor. IDLs can be compared to ABI files for EVM, which gives developers easy understanding of program structures.&lt;/p&gt;
&lt;h4&gt;
  
  
  Why are IDLs very useful
&lt;/h4&gt;

&lt;p&gt;While the applications of IDLs can be enumerated to varying use cases, IDLs are very useful for the main reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;They make program interaction human-readable&lt;/strong&gt;: Through IDLs, we can demystify the concatenation of transactions and accounts as just a bunch of bytes and provide developers a medium to easily parse instructions or accounts to make sense of what the program is doing. This attribute of IDLs enables indie and professional developers to get smooth integration on explorers, consumer UIs, and data platforms (like Dune).Below is an example of a parsed transaction instruction on Solana:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pu5ox5yikuyvblq0e5e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pu5ox5yikuyvblq0e5e.png" alt="an example of a parsed transaction instruction on Solana" width="800" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is an example of how Solana explorer display public IDLs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2j3wo3s3qhepgsqt11ar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2j3wo3s3qhepgsqt11ar.png" alt=" " width="800" height="675"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Providing Standard Interfacing:&lt;/strong&gt; By leveraging a standard interface, tools and frameworks can take advantage of this to generate instructions to interact with a program more easily, therefore enabling easier composability between program interfaces, making building client-side code far simpler &lt;strong&gt;(A good example would be the case of embedded wallet providers that whitelist specific ix discriminant)&lt;/strong&gt;. Below, we have an example of two &lt;em&gt;Hello World&lt;/em&gt; frontends that create a greeting account, one using Native Solana and the other using Anchor:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Using Native Solana:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const GREETING_SEED = 'hello'
const greetedPubkey = await PublicKey.createWithSeed(
    payer.publicKey,
    GREETING_SEED,
    programId
)

// Check if the greeting account has already been created
const greetedAccount = await connection.getAccountInfo(greetedPubkey)
if (greetedAccount === null) {
    console.log('Creating account', greetedPubkey.toBase58(), 'to say hello to')
    const lamports = await connection.getMinimumBalanceForRentExemption(
        GREETING_SIZE
    )

    const transaction = new Transaction().add(
        SystemProgram.createAccountWithSeed({
            fromPubkey: payer.publicKey,
            basePubkey: payer.publicKey,
            seed: GREETING_SEED,
            newAccountPubkey: greetedPubkey,
            lamports,
            space: GREETING_SIZE,
            programId,
        })
    )
    await sendAndConfirmTransaction(connection, transaction, [payer])
}
// ...
export async function sayHello(): Promise&amp;lt;void&amp;gt; {
    console.log('Saying hello to', greetedPubkey.toBase58())
    const instruction = new TransactionInstruction({
        keys: [{ pubkey: greetedPubkey, isSigner: false, isWritable: true }],
        programId,
        data: Buffer.alloc(0), // All instructions are hellos
    })
    await sendAndConfirmTransaction(
        connection,
        new Transaction().add(instruction),
        [payer]
    )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Source: https://github.com/solana-labs/example-helloworld/blob/master/src/client/hello_world.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using Anchor:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const anchor = require('@project-serum/anchor')

async function greet(message: string) {
    anchor.setProvider(anchor.Provider.local())
    // Here we load the HelloAnchor example IDL
    const program = anchor.workspace.HelloAnchor
    let greetKey = Keypair.generate()
    await program.methods
        .initialize(message)
        .accounts({
            newAccount: greetKey.publicKey,
            signer: wallet.publicKey,
            systemProgram: web3.SystemProgram.programId,
        })
        .signers([wallet, greetKey])
        .rpc()
}

greet('Hello World')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By utilizing IDLs, Anchor can abstract the process so that it is much easier to read, quicker to deploy, and more composable for CPI interactions. To know more about CPIs and why they are so crucial to Solana development, refer to this article &lt;a href="https://dev.to/aseneca/cross-program-invocations-and-pdas-the-combination-of-two-powerful-mechanism-on-anchor-4b93"&gt;Cross-Program Invocations and PDAs- the combination of two powerful mechanism on Anchor &lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dependency-free SDKs&lt;/strong&gt;: IDLs provide dependency-free SDKs for long-tail of Solana programs with &lt;code&gt;declare_program!()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating IDLs
&lt;/h2&gt;

&lt;p&gt;With Anchor, IDLs are automatically generated when you build because they are so integral to the entire anchor programming landscape. From the anchor project directory, enter the following in your terminal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;anchor build --idl &amp;lt;IDL_OUTPUT_DIRECTORY&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;However by default, &lt;code&gt;idl.json&lt;/code&gt; will be saved in &lt;code&gt;./target/idl&lt;/code&gt; folder&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5thbbflrecutv3vnontk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5thbbflrecutv3vnontk.png" alt=" " width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Solana programs written in native Rust, IDLs can be generated using tooling like &lt;a href="https://github.com/metaplex-foundation/shank" rel="noopener noreferrer"&gt;Metaplex Shank&lt;/a&gt; or &lt;a href="https://github.com/codama-idl/codama?tab=readme-ov-file" rel="noopener noreferrer"&gt;Codama Kinobi&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Publishing IDLs
&lt;/h3&gt;

&lt;p&gt;Anchor also makes it easy to publish IDLs on-chain. To do this, you simply need to enter the following in your terminal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;anchor idl init --filepath &amp;lt;FILEPATH&amp;gt; &amp;lt;PROGRAM_ID&amp;gt; --provider.cluster &amp;lt;CLUSTER&amp;gt; --provider.wallet &amp;lt;WALLET&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make sure the wallet being used is the program authority and has SOL for the on-chain transaction!&lt;/strong&gt; After the IDL is loaded, you should be able to see the IDL on Solana Explorer at &lt;a href="https://explorer.solana.com/address/YOUR_PROGRAM_ID/anchor-program" rel="noopener noreferrer"&gt;https://explorer.solana.com/address/YOUR_PROGRAM_ID/anchor-program&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Anchor &lt;code&gt;idl&lt;/code&gt; command has several other handy tools that enables developers to fetch, update, or freeze an IDL. For information on each of those commands, you can enter the following in your terminal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;anchor idl -h&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Interfacing IDLs on the Client Side
&lt;/h2&gt;

&lt;p&gt;Programs defined in your IDL are mapped to correspond to functions provided by the generated Typescript module, which is integrated into the front end of our application. The general structure of this module is outlined below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Program, AnchorProvider, setProvider } from '@project-serum/anchor'
import { Connection, KeyPair } from '@solana/web3.js'
import { PROGRAM_ID, IDL } from './your-program-dir'
// where IDL is the .json created by anchor build
// and PROGRAM_ID is your on-chain program ID

export const yourFunction = async () =&amp;gt; {
    const wallet = KeyPair.generate()
    const connection = new Connection(QN_ENDPOINT)
    const provider = new AnchorProvider(connection, wallet, {})
    setProvider(provider)
    const program = new Program(IDL, PROGRAM_ID)
    // ... your code
    // e.g. await program.methods.yourMethod(YOUR_PARAMETERS).accounts({YOUR_ACCOUNTS}).rpc();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Due to the program instructions and account embedded in the IDL, the code editor can automatically detect callable programs via &lt;code&gt;program.methods...&lt;/code&gt; A type guard is put in place to ensure all the necessary accounts are passed into the instruction. See &lt;a href="https://solana.com/developers/courses/onchain-development/intro-to-anchor-frontend" rel="noopener noreferrer"&gt;Intro to client-side Anchor development&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaobcyv1vf6j62dbfpt6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaobcyv1vf6j62dbfpt6.png" alt="Client-side anchor devlopment" width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Improving IDL Discoverability
&lt;/h3&gt;

&lt;p&gt;The majority of programs use Anchor today, and for non-Anchor frameworks, &lt;a href="https://github.com/codama-idl/codama" rel="noopener noreferrer"&gt;codama&lt;/a&gt; coupled with verified builds can fill the gaps. These IDLs provide efficient reading and a starting point for calling programs with &lt;code&gt;declare_program!()&lt;/code&gt; but they are currently not discoverable. It is not yet ascertained whether IDLs can cover all possibilities on programs however the majority can be covered.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjjcitml54w8dv7onmcrp.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjjcitml54w8dv7onmcrp.jpeg" alt=" " width="680" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Current solutions being proposed to improve discoverability have to satisfy the following requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Must allow a generalized reading from the network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The time taken to understand how to implement CPI into other programs should be significantly reduced.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Program discovery should be as frictionless as possible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have explored IDLs and their numerous benefits. We have also examined IDLs in Anchor and non-Anchor frameworks and how developers can utilize them to improve program composability. &lt;/p&gt;

&lt;p&gt;However, existing infrastructure does not have versioned IDLs based on deployment time, which makes it difficult for developers concerned with consistent data integration to understand what IDL to use at what slot.&lt;/p&gt;

&lt;p&gt;Improving IDL discoverability has huge benefits; developers can easily integrate CPI into programs, which expands composability within the general developer landscape, unlocking new use cases that may not have been thought of.&lt;/p&gt;

&lt;p&gt;Discoverable IDLs also provide more insight into security deficiencies as even seasoned developers on Solana tend to secure their program through obscurity which can often prove to be a bug rather than a feature.&lt;/p&gt;

&lt;p&gt;Over the coming years, IDLs are beginning to take a place within the spotlight as targets for more investment and development to enable building on Solana a more framework and language agnostic process, therefore &lt;strong&gt;accelerating developer experience across all development landscapes on Solana.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Additional Resources/Further Reading
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.anchor-lang.com/" rel="noopener noreferrer"&gt;Anchor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/metaplex-foundation/shank" rel="noopener noreferrer"&gt;Metaplex shank &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://solana.com/developers/courses/onchain-development/intro-to-anchor-frontend" rel="noopener noreferrer"&gt;Intro to client-side Anchor development&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>solana</category>
      <category>idl</category>
      <category>anchor</category>
    </item>
    <item>
      <title>Handling Text in Rust: String and &amp;Str</title>
      <dc:creator>Aseneca</dc:creator>
      <pubDate>Tue, 15 Oct 2024 18:37:30 +0000</pubDate>
      <link>https://forem.com/aseneca/handling-text-in-rust-string-and-str-3icc</link>
      <guid>https://forem.com/aseneca/handling-text-in-rust-string-and-str-3icc</guid>
      <description>&lt;p&gt;Unlike other programming languages, handling text in rust can be a bit complicated. This is due to some type-handling mechanism that rust forces us to adhere to in order to mitigate any problems that might result from the "text-structure and usage" at compile time. Rust uses two types to identify "text-based" characters. These are String and &amp;amp;Str. They are very similar in many ways but differ in terms of ownership, mutability and how they are represented in memory. &lt;/p&gt;

&lt;h2&gt;
  
  
  String Type
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;String type&lt;/code&gt; is a heap-allocated owned string. This means that its size is dynamic and can adjust to the needs at runtime.&lt;br&gt;
Also, the String type is mutable which implies that you can either append characters or change characters in the &lt;code&gt;String type&lt;/code&gt;. This &lt;em&gt;mutability&lt;/em&gt; is possible because the String type &lt;strong&gt;owns&lt;/strong&gt; the memory that it uses.&lt;br&gt;
for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let mut s= String::from("Hello");
s.push(", World"); //we modify the string s
println!("{}", s);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we say the String type size is dynamic, we mean that it is allowed by rust to grow and shrink as needed as demonstrated in the simple example above.&lt;/p&gt;

&lt;h2&gt;
  
  
  &amp;amp;Str Type
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;&amp;amp;Str type&lt;/code&gt; on the other hand refers to a borrowed string slice. It is used to represent a &lt;strong&gt;view&lt;/strong&gt; into a part of a string but it does not &lt;strong&gt;own&lt;/strong&gt; the memory to which it point(because it is borrowed). Unlike the &lt;code&gt;String type&lt;/code&gt;, the &lt;code&gt;&amp;amp;Str type&lt;/code&gt; is an immutable reference usually alluded to a String type or a string literal. Therefore its data cannot be modified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let s= "This is a rust example" //this is a &amp;amp;str
printlin!("{}", s)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let s= String::from("Rust is awesome"); //this is a String
let sliced_string: &amp;amp;str= &amp;amp;s[0..5]; //&amp;amp;str(string slice)
printlin!("{}", sliced_string)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  String Literals
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;String literals&lt;/code&gt; in rust are also &lt;code&gt;&amp;amp;str types&lt;/code&gt;. This means they are also stored the program's binary at compile time and are immutable.&lt;/p&gt;

&lt;p&gt;for example,&lt;br&gt;
&lt;code&gt;let greeting= "Hello"; //this is a &amp;amp;str&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Conversion between &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;&amp;amp;Str&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can convert a &lt;code&gt;&amp;amp;str&lt;/code&gt; to a &lt;code&gt;String&lt;/code&gt; using the &lt;code&gt;String::from&lt;/code&gt; function or the &lt;code&gt;.to_string()&lt;/code&gt; Method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let heading: &amp;amp;str="A letter to rust";
let heading_string:String= heading.to_string()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other hand conversion from &lt;code&gt;String&lt;/code&gt;to &lt;code&gt;&amp;amp;str&lt;/code&gt; is not as straight-forward as you will have to borrow the String content. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;let heading= String::from("A letter to rust");&lt;br&gt;
let slice_heading:&amp;amp;str= &amp;amp;heading; //borrow heading as a &amp;amp;str&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Now that you know the difference between &amp;amp;str and String, when should you use them?
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;String&lt;/code&gt;when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ownership over the string&lt;/li&gt;
&lt;li&gt;To modify the string at some point&lt;/li&gt;
&lt;li&gt;To store a dynamic string i.e a string which you do not know the size at compile time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use &lt;code&gt;&amp;amp;Str&lt;/code&gt; when you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do not need to own the string&lt;/li&gt;
&lt;li&gt;Require a reference to the string without making a copy or clone&lt;/li&gt;
&lt;li&gt;Do not need to modify the string at any point&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope this article has helped you understand more about &lt;code&gt;&amp;amp;str&lt;/code&gt; and &lt;code&gt;String&lt;/code&gt; and how they provide great flexibility when it comes to handling string data in different contexts.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Clone and Iterative Adapter Methods in Rust: The thin line between Duplication, Efficiency and Transformation</title>
      <dc:creator>Aseneca</dc:creator>
      <pubDate>Sat, 21 Sep 2024 12:43:39 +0000</pubDate>
      <link>https://forem.com/aseneca/clone-and-iterative-adapter-methods-in-rust-the-thin-line-between-duplication-efficiency-and-transformation-e0g</link>
      <guid>https://forem.com/aseneca/clone-and-iterative-adapter-methods-in-rust-the-thin-line-between-duplication-efficiency-and-transformation-e0g</guid>
      <description>&lt;p&gt;As a rust developer, it is a dilemma you would always have to deal with: the choice between clone and iterative methods. In this guide, we will be exploring what these methods are, the fundamental differences between them, how they can be useful in manipulating data and which is appropriate for particular situations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Clone method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The clone method (clone()) is used to implement or "create" deep copies of an object or data. It operates by &lt;strong&gt;duplicating&lt;/strong&gt; the entire object structure and &lt;strong&gt;reallocating&lt;/strong&gt; new memory for the copied instance of that object. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: When we refer to the term  reallocating, this is most likely a reference to &lt;code&gt;heap-allocated data&lt;/code&gt; i.e. dynamic allocated memory for complex data collections(e.g., String, Vec, Box). When using clone() with stack-only types (e.g., char, i32), we do not reallocate memory as it simply copies the data directly on the stack.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In simpler terms, the clone method generates two independent instances of the same data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn main() {
    let args: Vec&amp;lt;String&amp;gt; = env::args().collect();

    let config = parse_config(&amp;amp;args);

    println!("Searching for {}", config.query);
    println!("In file {}", config.file_path);

    let contents = fs::read_to_string(config.file_path)
        .expect("Should have been able to read the file");

    // --snip--
}

struct Config {
    query: String,
    file_path: String,
}

fn parse_config(args: &amp;amp;[String]) -&amp;gt; Config {
    let query = args[1].clone();
    let file_path = args[2].clone();

    Config { query, file_path }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;In the code snippet above, we make a full copy of the data for the &lt;code&gt;Config&lt;/code&gt; instance to own by cloning the values received through &lt;code&gt;args&lt;/code&gt;, which takes more time and memory than storing a reference to the string data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Iterator Adapter Method&lt;/strong&gt;&lt;br&gt;
 In comparison to the clone(), iterator adapter methods are used to transform and process elements of an iterator. They are usually referred to as &lt;code&gt;lazy&lt;/code&gt; in rust, and this is because iterator methods will not effect any process until the methods that consume the iterator is called. These consumption methods also known as &lt;code&gt;consuming adapters&lt;/code&gt;, i.e methods that use up the  (e.g., sum(), next()….) will be discussed when we talk about iterator methods in details. &lt;br&gt;
&lt;strong&gt;Iterator Adapters&lt;/strong&gt;(different from consuming adapters) do not immediately produce new data, hence the term "lazy'. Instead they return a new iterator that processes these data as they are needed on demand.&lt;/p&gt;
&lt;h2&gt;
  
  
  Differences between Clone Methods and Iterator Adapter Methods
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Memory Allocation:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Clone Method:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Clone methods will create a new copy of the data. This can lead to additional memory allocation and therefore can be computationally expensive, especially for large or complex data structures, as it requires duplicating the entire object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let v = vec![1, 2, 3];
let v2 = v.clone(); // Creates a deep copy of the entire vector
println!("{:?}, {:?}", v, v2);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Iterator Adapter Method:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Iterators generally operate in a &lt;code&gt;lazy&lt;/code&gt; fashion, so they will not allocate memory immediately. They transform or process data as you iterate over it and this can make them more memory-efficient than clone methods. Also, allocation with iterators occurs only when you consume the iterator (e.g., using .collect() to gather results into a new collection).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let v = vec![1, 2, 3];
let iter = v.iter().map(|x| x * 2); // Creates a lazy iterator, no memory allocation yet
let v2: Vec&amp;lt;_&amp;gt; = iter.collect();    // Consumes the iterator and collects the results into a new vector
println!("{:?}, {:?}", v, v2);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data Ownership and Borrowing:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Clone Method:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When an object is cloned, a new owned instance of that object data is initiated. Therefore, both the original and the cloned object can co-exist independently with no ownership conflict between them. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Iterator Adapter Method:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Iterators can either borrow data from the original collection or take ownership of the elements. Many iterator methods do not require ownership (for example, the &lt;code&gt;iter()&lt;/code&gt; returns an iterator that borrows the data).&lt;br&gt;&lt;br&gt;
This borrowing mechanism is very useful when you need multiple copies of data that can be modified separately therefore making them more flexible when you want to process elements without transferring ownership or duplicating data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So now you know the difference between them, which should you use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well it is going to depend on your specific use case but as a general rule of thumb, You use clone methods when you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;wish to create a deep copy of an object, instantly allocating new memory for the instance.&lt;/li&gt;
&lt;li&gt;want an independent, identical copy of an object that can be modified or passed elsewhere without affecting the original object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;You use Iterator Adapter Methods when you:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;want to transform, filter, or aggregate data from a collection or stream in a lazy, efficient way.&lt;/li&gt;
&lt;li&gt;Do not need immediate memory allocation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But here is something you should keep in mind, aside from the specific use cases considered above, clone methods are generally inefficient because of its runtime cost. The idea of deeply copy data can impact performance especially if it is a large and complex data. &lt;br&gt;
Iterative methods on the other hand are more efficient since you do not need to create any intermediate collections unless explicitly required by the program.&lt;br&gt;
Iterative methods are also more performant efficient than &lt;code&gt;loops&lt;/code&gt;. By combining them with closures, which we shall talk about when we discuss Iterative adapters in detail, we can harness Rust’s capability to clearly express high-level ideas at low-level performance.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>solana</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Introduction to Solana: A fledging's guide on Web3 development on Solana</title>
      <dc:creator>Aseneca</dc:creator>
      <pubDate>Tue, 17 Sep 2024 09:48:21 +0000</pubDate>
      <link>https://forem.com/aseneca/introduction-to-solana-a-fledgings-guide-on-web3-development-on-solana-1jg3</link>
      <guid>https://forem.com/aseneca/introduction-to-solana-a-fledgings-guide-on-web3-development-on-solana-1jg3</guid>
      <description>&lt;p&gt;In this guide, we will be briefly explaining important web3 concepts such as blockchain, protocols etc. Then we shall dive deeper into key development concepts in Solana blockchain which should serve as an entry point for new Solana developers or blockchain enthusiasts that wish to learn further about Solana.&lt;/p&gt;

&lt;p&gt;First of all, let's talk about fundamental terminologies that exist across web3 in general:&lt;/p&gt;

&lt;h4&gt;
  
  
  Blockchain
&lt;/h4&gt;

&lt;p&gt;A blockchain can be thought of as a series of blocks or an append-only data structure that resembles an ordered back-linked linked list, which uses hashes as pointers to previous blocks. This structure consists of blocks that form a chain, hence the term blockchain. This is a very simple data structure model but it can get more complex than this with different approaches to how these blocks interact with one another&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhefphs09ehcljcrf03nn.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhefphs09ehcljcrf03nn.PNG" alt="Simple Scheme of Blockchain" width="574" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Block
&lt;/h4&gt;

&lt;p&gt;A typical Block is a data structure that contains a header comprising three items– the hash of the previous block’s header, metadata and a Merkle root. Metadata depends on the protocol. The Merkle root is a root of the well-known Merkle tree, which can be used to verify later that transactions in a block have not been tampered with. After the head comes the core part of the block, the transaction.&lt;/p&gt;

&lt;h4&gt;
  
  
  Transaction
&lt;/h4&gt;

&lt;p&gt;Transaction is a protocol-defined message that is stored as a part of a block, which is then stored as a part of a blockchain. The content usually consists of some kind of value transfer or on-chain program execution. Transactions are cryptographically signed by their authors or authority, proving their authenticity. In the case of a value transfer, ownership of the funds or tokens often represents some value in the real world.&lt;/p&gt;

&lt;h4&gt;
  
  
  Protocol
&lt;/h4&gt;

&lt;p&gt;Protocol in simple and familiar terms refer to a common set of rules network nodes must follow. It defines the ground rules for communication between P2P (Peer-to-Peer) nodes, transaction format for everyone intending to use the network, any special features, and everything else for the network to operate correctly and for the users to know how to transact over the network. An essential part of a good protocol for a decentralized blockchain network is the proper incentive setup; this creates the need for its native token. Examples include SOL(token) for Solana (chain), ETH(token) for Ethereum(chain), BTC for Bitcoin &lt;/p&gt;

&lt;h4&gt;
  
  
  Smart contracts
&lt;/h4&gt;

&lt;p&gt;A smart contract is a piece of code deployed on a blockchain with a cryptographically signed transaction. Users can then interact with it by sending transactions that invoke a specific function defined in the smart contract and the business logic is executed as stated in the deployed code.&lt;br&gt;
Smart contracts on Solana are called Programs.&lt;br&gt;
Data pertinent to the smart contract "state" are also stored on on-chain. A good analogy would be to compare smart contracts as programs on a decentralized computer that access files in its file system and modify them according to the predefined rules. Such a contract can be made immutable or mutable. If such a contract is made immutable, we can trust that the smart contract will not do anything else than what it is supposed to do.&lt;/p&gt;

&lt;p&gt;Okay great. Now we know a little about what blockchain is and its rudimentary building blocks. Lets dive into the blockchain of interest in this guide: Solana.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Solana?&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  SOLANA
&lt;/h3&gt;

&lt;p&gt;Solana is a single-chain blockchain that utilizes a slightly changed PBFT consensus called Tower BFT with Proof-of-Stake as a Sybil protection mechanism. It was engineered with composability at its core, meaning its performance does not depend on hardware. It is able to adapt to any hardware and scale to the utilize the full power of that "hardware."&lt;br&gt;
Solana is a smart contract platform but smart contracts on Solana are called Programs. Programs can be executed in parallel. This parallelization is one of the key USP that gives Solana its composability nature. &lt;br&gt;
Compared to Ethereum which is written in Solidity, development of Programs on Solana revolve around Rust programming language and its frameworks especially Anchor. &lt;br&gt;
We will be breaking down the core concepts of Solana that come together to redefine its engineering perspective and improve its scalability in a subsequent article because those are more advanced concepts beyond the scope of this guide.&lt;/p&gt;
&lt;h4&gt;
  
  
  The Essentials of Solana Smart Contracts (Programs)
&lt;/h4&gt;

&lt;p&gt;One thing you should have on the back of your mind as you explore building on Solana is: everything in Solana is an account. Accounts are owned by programs.&lt;br&gt;
There are core concepts we need to discuss to help you understand how programs operate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Transactions&lt;/li&gt;
&lt;li&gt;Instructions&lt;/li&gt;
&lt;li&gt;Accounts&lt;/li&gt;
&lt;li&gt;Program Derived Addresses(PDAs)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;1. Transactions&lt;/strong&gt;&lt;br&gt;
   A transaction is a signed instruction sequence that is executed atomically. They are used to interact with programs deployed on the Solana network. A transaction is made up of one or more &lt;code&gt;instructions&lt;/code&gt;, &lt;code&gt;a recent blockhash&lt;/code&gt;, and &lt;code&gt;signatures&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The recent blockhash, also known as a transaction "recentBlockhash", is used for transaction processing and lifespan. The signatures are the cryptographic proof of the transaction's integrity and authority. Each transaction must be signed by the appropriate account holders as per the instructions contained within. This takes us to the next concept which are instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Instructions&lt;/strong&gt;&lt;br&gt;
   Instructions in Solana are "bundled" within a transaction and are executed sequentially. Each instruction contains a&lt;code&gt;program ID&lt;/code&gt;, accounts that it wishes to interact with, and a &lt;code&gt;data field&lt;/code&gt;. The program ID specifies the on-chain program that will process the instruction. The &lt;code&gt;accounts array&lt;/code&gt; includes all accounts that the instruction will read from or write to. The accounts array must include at least one signer (authority) who authorizes the instruction.&lt;/p&gt;

&lt;p&gt;The data field is an arbitrary byte array that is passed to the program for processing. &lt;br&gt;
It is this combination of transactions and instructions that allows for high throughput and efficient processing in Solana. By virtue of its architecture design, Solana is capable of processing thousands of transactions per second, each containing multiple instructions, which can interact with different programs and accounts. This design can also be attributed to Solana's core scalability and speed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Accounts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Solana, an account is a persistent memory structure that a program can use for storing state. Every account in Solana is initially owned by the system program, but the system program can change the ownership if the correct private key for the account is provided. Each account includes several properties:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a. Public Key (Pubkey):&lt;/strong&gt; This is the unique identifier of the &lt;br&gt;
     account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;b. Signer Flag (is_signer):&lt;/strong&gt; This flag indicates whether the account &lt;br&gt;
   is a signer of the transaction. If true, the transaction must &lt;br&gt;
    include the signature of this account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;c. Writable Flag (is_writable):&lt;/strong&gt; This flag indicates whether the &lt;br&gt;
    data in the account can be modified. If true, the account's data &lt;br&gt;
    can be written to in the current transaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;d. Lamports:&lt;/strong&gt; This is the number of lamport's (the smallest unit of &lt;br&gt;
     the native SOL token) held in the account. Lamports also serve as &lt;br&gt;
     rent to keep the account on the network. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;e. Data:&lt;/strong&gt; This is a byte array that can hold arbitrary data. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;f. Owner:&lt;/strong&gt; This is another public key that identifies the program &lt;br&gt;
     that has authority over the account's data. Only the owner program &lt;br&gt;
     can modify the account's data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;g. Executable Flag:&lt;/strong&gt; Hold if the account is a smart contract. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;h. Rent Epoch:&lt;/strong&gt; This value represents the latest epoch that rent has &lt;br&gt;
   been paid for the account. Rent is paid in SOL and ensures that the &lt;br&gt;
   account remains active on the network.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In Solana, accounts not only hold the state of a program but can also be used to create complex relationships between different programs through CPIs (&lt;a href="https://dev.to/aseneca/cross-program-invocations-and-pdas-the-combination-of-two-powerful-mechanism-on-anchor-4b93"&gt;See more on CPIs here&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Getting started on Solana Development
&lt;/h3&gt;

&lt;p&gt;To get started with Solana development, you would need a (MacOS) or a Linux development environment. You can also use WSL on windows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install Rust, Rustup and Cargo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open up a terminal window (for MacOS) or command prompt (for Windows) and paste this command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we have installed Rust language and Cargo (the Rust package manager)which is required for compiling Rust-based Solana programs. &lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Install Solana Tool Suite&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing for MacOS &amp;amp; Linux&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This option is easier but it requires you to have Homebrew package manager on your MacOS or Linux machine.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install solana&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can confirm you have the desired version of Solana installed by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;solana --version&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing for MacOS &amp;amp; Linux (without homebrew)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install the &lt;strong&gt;Solana release v1.18.7&lt;/strong&gt; on your machine by running: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;sh -c "$(curl -sSfL https://release.solana.com/v1.18.17/install)"&lt;/code&gt;&lt;br&gt;
You can confirm you have the desired version of solana installed by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;solana --version&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Windows&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open a Command Prompt &lt;code&gt;cmd.exe&lt;/code&gt; as an Administrator and paste this command:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
cmd /c "curl https://release.solana.com/v1.18.17/solana-install-init-x86_64-pc-windows-msvc.exe --output C:\solana-install-tmp\solana-install-init.exe --create-dirs"&lt;/code&gt;&lt;br&gt;
Copy and paste the following command, then press Enter to install the latest version of Solana. If you see a security pop-up by your system, please select to allow the program to run.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;C:\solana-install-tmp\solana-install-init.exe v1.18.17&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can confirm you have the desired version of solana installed by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;solana --version&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In addition, ensure you have &lt;a href="https://nodejs.org/en/download/package-manager" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; and &lt;a href="https://classic.yarnpkg.com/lang/en/docs/install/#windows-stable" rel="noopener noreferrer"&gt;Yarn&lt;/a&gt; installed on your computer&lt;br&gt;
&lt;em&gt;Now you have Solana Cli, Node.Js and Yarn installed, lets go ahead and create a Keypair&lt;/em&gt; &lt;/p&gt;
&lt;h4&gt;
  
  
  Creating Keypair
&lt;/h4&gt;

&lt;p&gt;To get started, we're going to create a keygen script and an airdrop script for our account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting up&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Opening up your Terminal and use yarn to create a new Typescript project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install touch-cli -g
mkdir airdrop &amp;amp;&amp;amp; cd airdrop
yarn init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;If you get an error in windows after &lt;code&gt;yarn init -y&lt;/code&gt;, run Microsoft powershell as administrator and run the following code:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Set-ExecutionPolicy RemoteSigned&lt;br&gt;
This will initialize a new project, we're going to go ahead and add typescript, bs58 and @solana/web3.js, along with generating a tsconfig.js configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @types/node typescript @solana/web3.js bs58
yarn add -D ts-node
touch keygen.ts
touch airdrop.ts
touch transfer.ts
yarn tsc --init --rootDir ./ --outDir ./dist --esModuleInterop --lib ES2019 --module commonjs --resolveJsonModule true --noImplicitAny true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we're going to create some scripts in our package.json file to let us run the three scripts we're going to build today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "airdrop",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "keygen": "ts-node ./keygen.ts",
    "airdrop": "ts-node ./airdrop.ts",
    "transfer": "ts-node ./transfer.ts",
  },
  "dependencies": {
    "@solana/web3.js": "^1.75.0",
    "@types/node": "^18.15.11",
    "typescript": "^5.0.4"
  },
  "devDependencies": {
    "ts-node": "^10.9.1"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;❗ Ensure to add the scripts part to the .json file. ❗&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generating a Keypair&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open up &lt;code&gt;./keygen.ts.&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Importing Keypair from @solana/web3.js&lt;/em&gt;&lt;br&gt;
&lt;code&gt;&lt;br&gt;
import { Keypair } from "@solana/web3.js";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Generate a new keypair:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Generate a new keypair
let kp = Keypair.generate()
console.log(`You've generated a new Solana wallet: ${kp.publicKey.toBase58()}`);
console.log(`Solana Wallet Secret Key: ${kp.secretKey}]`);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;run the following script to generate a new keypair!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn keygen&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will generate a new Keypair, outputting its Address and Private Key like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You've generated a new Solana wallet: 2sNvwMf15WPp94kywgvfn3KBNPNZhr5mWrDHmgjkjMhN
Solana Wallet Secret Key: 63,224,142,27,16,71,3,47,65,3,83,69,169,184,116,97,218,0,1,213,225,174,108,112,40,67,255,32,77,82,140,62,187,6,73,117,82,29,152,252,161,62,35,24,148,199,196,160,92,62,81,179,17,49,7,202,226,213,201,30,73,176,198,11]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Best practice would be to save this wallet locally. runthe following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;touch dev-wallet.json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This creates the file dev-wallet.json in our ./airdrop root directory.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Now paste the private key from above into this file in this format:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;[63,224,142,27,16,71,3,47,65,3,83,69,169,184,116,97,218,0,1,213,225,174,108,112,40,67,255,32,77,82,140,62,187,6,73,117,82,29,152,252,161,62,35,24,148,199,196,160,92,62,81,179,17,49,7,202,226,213,201,30,73,176,198,11]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Congratulations. You've just created a new Keypair and saved first your wallet. Now, Let's go claim some tokens!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claiming Airdrop Tokens&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;import &lt;code&gt;Keypair&lt;/code&gt;, also going to import &lt;code&gt;Connection&lt;/code&gt; to  establish a connection to the &lt;code&gt;Solana devnet&lt;/code&gt;, and &lt;code&gt;LAMPORTS_PER_SOL&lt;/code&gt; to transfer amounts denominated in SOL rather than individual lamports units.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Connection, Keypair, LAMPORTS_PER_SOL } from "@solana/web3.js"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;get the private key in the .json file by importing the wallet and recreate the Keypair object using its private key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import wallet from "./dev-wallet.json"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;import the keypair from the wallet file&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const keypair = Keypair.fromSecretKey(new Uint8Array(wallet));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;establish a connection to the Solana devnet&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Create a Solana devnet connection to devnet SOL tokens
const connection = new Connection("https://api.devnet.solana.com");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Finally, claim 2 devnet SOL tokens:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(async () =&amp;gt; {
    try {

        const txhash = await connection.requestAirdrop(keypair.publicKey, 2 * LAMPORTS_PER_SOL);
        console.log(`Success! Check out your TX here: 
        https://explorer.solana.com/tx/${txhash}?cluster=devnet`);
    } catch(e) {
        console.error(`Oops, something went wrong: ${e}`)
    }
})();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Save the code and run it by typing yarn airdrop in the terminal. You should get a successful message with a Tx address.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Congratulations once again for coming this far. You are officially a Solana newbie dev now. But why stop here: As a challenge, try implementing the transfer token challenge and share your result in the comment section.&lt;/p&gt;

</description>
      <category>solana</category>
      <category>web3</category>
      <category>blockchain</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cross-Program Invocations and PDAs- the combination of two powerful mechanism on Anchor</title>
      <dc:creator>Aseneca</dc:creator>
      <pubDate>Wed, 11 Sep 2024 18:58:06 +0000</pubDate>
      <link>https://forem.com/aseneca/cross-program-invocations-and-pdas-the-combination-of-two-powerful-mechanism-on-anchor-4b93</link>
      <guid>https://forem.com/aseneca/cross-program-invocations-and-pdas-the-combination-of-two-powerful-mechanism-on-anchor-4b93</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcuotuw9dux336gh2he2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcuotuw9dux336gh2he2.png" alt=" " width="800" height="499"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;As an intermediate anchor developer building on Solana&lt;/strong&gt;, it is very likely you would eventually come across a situation where it is more beneficial for your programs to interact with one another. Such composability in Solana is achieved through a mechanism called &lt;strong&gt;Cross-Program Invocations&lt;/strong&gt; (CPIs).&lt;/p&gt;

&lt;p&gt;Let us first break down what CPIs are, how you should use them and what you should keep in mind while using this functionality.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cross-Program Invocation(CPIs)
&lt;/h2&gt;

&lt;p&gt;The unique integrated architecture of Solana is what gives it the ability to process thousands of transactions per second while leveraging a globally decentralized network. This design gives room for a sort of modular structure, while acting as a single-chain blockchain that enables applications built on top of it inherit composability. This composable topology is what enable applications(and programs) to interact and build on top one another eliminating the need for complex on-chain activities such ass bridging and liquidity fragmentation.&lt;/p&gt;

&lt;p&gt;CPIs are one of the internal mechanisms that enables a Solana program (or smart contract) to call another program on the blockchain during its execution. It is a powerful mechanism that gives different programs the ability to interact and perform actions like token transfers, data manipulation, or other operations defined by the source program.&lt;/p&gt;
&lt;h3&gt;
  
  
  when should you use CPIs?
&lt;/h3&gt;

&lt;p&gt;You should use CPIs when you need a program to leverage another program to execute a functionality. for example, like performing a token transfer, using a CPI to leverage the Token Program will save us a lot of computational resource instead of re-implementing the token transfer functionality or in transferring an NFT from one account to another.&lt;/p&gt;
&lt;h3&gt;
  
  
  How would you use a CPI?
&lt;/h3&gt;

&lt;p&gt;Basically using a CPI involve the following steps:&lt;/p&gt;

&lt;p&gt;firstly identifying the programs you wish to interact with. We shall be using the Token program as an example. &lt;/p&gt;

&lt;p&gt;Then define the necessary accounts that would be required by the CPI using Anchor's #[account] macros, and specify the constraints that define how they should be passed into the CPI as shown in the example below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Accounts)]
pub struct List&amp;lt;'info&amp;gt; {
    #[account(mut)]
    maker: Signer&amp;lt;'info&amp;gt;,
    #[account(
        seeds = [b"marketplace", marketplace.name.as_str().as_bytes()],
        bump = marketplace.bump,
    )]
    marketplace: Box&amp;lt;Account&amp;lt;'info, Marketplace&amp;gt;&amp;gt;,
    maker_mint: Box&amp;lt;InterfaceAccount&amp;lt;'info, Mint&amp;gt;&amp;gt;,
    collection_mint: Box&amp;lt;InterfaceAccount&amp;lt;'info, Mint&amp;gt;&amp;gt;,
    #[account(
        mut,
        associated_token::authority = maker,
        associated_token::mint = maker_mint,
    )]
    maker_ata: Box&amp;lt;InterfaceAccount&amp;lt;'info, TokenAccount&amp;gt;&amp;gt;, //stores the maker on the heap
    #[account(
        init_if_needed,
        payer = maker,
        associated_token::mint = maker_mint,
        associated_token::authority = listing,
    )]
    vault: Box&amp;lt;InterfaceAccount&amp;lt;'info, TokenAccount&amp;gt;&amp;gt;,
    #[account(
        init,
        payer = maker,
        space = 8 + Listing::INIT_SPACE,
        seeds = [marketplace.key().as_ref(), maker_mint.key().as_ref()],
        bump
    )]
    listing: Box&amp;lt;Account&amp;lt;'info, Listing&amp;gt;&amp;gt;,
    #[account(
        seeds = [
            b"metadata",
            metadata_program.key().as_ref(),
            maker_mint.key().as_ref()
        ],
        seeds::program = metadata_program.key(),
        bump,
        constraint = metadata.collection.as_ref().unwrap().key.as_ref() == collection_mint.key().as_ref(),
        constraint = metadata.collection.as_ref().unwrap().verified == true,
    )]
    metadata: Box&amp;lt;Account&amp;lt;'info, MetadataAccount&amp;gt;&amp;gt;,
    #[account(
        seeds = [
            b"metadata",
            metadata_program.key().as_ref(),
            maker_mint.key().as_ref(),
            b"edition"
        ],
        seeds::program = metadata_program.key(),
        bump,
    )]
    master_edition: Box&amp;lt;Account&amp;lt;'info, MasterEditionAccount&amp;gt;&amp;gt;,
    metadata_program: Program&amp;lt;'info, Metadata&amp;gt;,
    associated_token_program: Program&amp;lt;'info, AssociatedToken&amp;gt;,
    system_program: Program&amp;lt;'info, System&amp;gt;,
    token_program: Interface&amp;lt;'info, TokenInterface&amp;gt;,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step would involve defining the instruction data, for example, defining the mechanism of the transfer from the maker_ata account to the vault account, establishing the maker account as the authority and the maker_mint account as the mint. The required accounts needed to deposit an NFT to a vaults were the&lt;code&gt;maker_ata account, vault account, maker and maker_mint account&lt;/code&gt;&lt;br&gt;
Then we create the &lt;code&gt;CPI context&lt;/code&gt; and invoke the token program transfer instruction&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn deposit_nft(&amp;amp;mut self) -&amp;gt; Result&amp;lt;()&amp;gt; {
        let accounts = TransferChecked {
            from: self.maker_ata.to_account_info(),
            to: self.vault.to_account_info(),
            authority: self.maker.to_account_info(),
            mint: self.maker_mint.to_account_info(),
        };

        //create a Cpi context
        let cpi_ctx = CpiContext::new(self.token_program.to_account_info(), accounts);

         // Invoke the token program’s transfer instruction
        transfer_checked(cpi_ctx, 1, self.maker_mint.decimals)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above example is also a form of an important benefit of CPIs known as &lt;strong&gt;Privilege Extensions&lt;/strong&gt; which as the name implies "extends" the privileges of the &lt;em&gt;caller to the callee.&lt;/em&gt; In our above example, the original authority &lt;code&gt;maker account&lt;/code&gt; "extends" the control of the authority to the &lt;code&gt;Token Program&lt;/code&gt; temporarily, enabling it to execute the transfer on its behalf for the duration of the invocation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Program as Signers
&lt;/h2&gt;

&lt;p&gt;It is very likely that in some cases, and this is most often the case, you would require that the program itself take authority over the assets. In the NFT marketplace example above, it is likely you would want a program to delist and even purchase an NFT on your behalf or a lending protocol program would need to manage deposited collateral and automated market maker programs need to manage the tokens put into their liquidity pools.&lt;br&gt;
We can accomplish this using Program Derived Addresses (PDAs). We will talk about PDAs in subsequent articles, but simply defined: PDAs are special addresses that do not have public keys and therefore do not have an associated private key. They have two advantages to build hashmap-like structures on-chain and the allow programs to sign instructions without private keys. &lt;/p&gt;

&lt;p&gt;PDAs combined with CPIs are very powerful features in anchor development as they allow us to securely manage assets and data by ensuring that only the owning program through the CPI can sign transactions that affect a particular account thus preventing unauthorized signings during inter-program communications.&lt;/p&gt;

&lt;p&gt;To sign a transaction with a PDA in through the CPI Context, instead of the calling the &lt;code&gt;CpiContext::new(cpi_program, accounts)&lt;/code&gt; method, we would have to use the &lt;code&gt;CpiContext::new_with_signer(cpi_program, accounts, seeds)&lt;/code&gt; where the seeds argument are the seeds and the bump the PDA was created with as shown in the &lt;code&gt;close_mint_vault&lt;/code&gt;implementation below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; pub fn close_mint_vault(&amp;amp;mut self) -&amp;gt; Result&amp;lt;()&amp;gt; {
        let seeds = &amp;amp;[
            &amp;amp;self.marketplace.key().to_bytes()[..],
            &amp;amp;self.maker_mint.key().to_bytes()[..],
            &amp;amp;[self.listing.bump],
        ];
        let signer_seeds = &amp;amp;[&amp;amp;seeds[..]];

        let accounts = CloseAccount {
            account: self.vault.to_account_info(),
            destination: self.maker.to_account_info(),
            authority: self.listing.to_account_info(),
        };
        //Sign with the pda
        let cpi_ctx = CpiContext::new_with_signer(
            self.token_program.to_account_info(),
            accounts,
            signer_seeds
        );

        close_account(cpi_ctx)
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;what happens here is that during execution, the Solana runtime will check whether &lt;code&gt;hash(seeds, current_program_id) == account address&lt;/code&gt; is true. If yes, that account's&lt;code&gt;is_signer&lt;/code&gt; flag will be turned to true. This means a PDA derived from some program, may only be used to sign CPIs that originate from that particular program. &lt;/p&gt;

&lt;p&gt;In summary, combining CPIs and PDAs enables us to leverage the powerful abstractive feature of Anchor while enabling us to reduce the number of accounts we need through PDAs and securing a composable interaction between different programs on our application.&lt;/p&gt;

</description>
      <category>anchor</category>
      <category>rust</category>
      <category>solana</category>
      <category>programming</category>
    </item>
    <item>
      <title>Advanced Developer Tutorial on Address Lookup Tables</title>
      <dc:creator>Aseneca</dc:creator>
      <pubDate>Thu, 16 Nov 2023 09:27:47 +0000</pubDate>
      <link>https://forem.com/aseneca/advanced-developer-tutorial-on-address-lookup-tables-3agg</link>
      <guid>https://forem.com/aseneca/advanced-developer-tutorial-on-address-lookup-tables-3agg</guid>
      <description>&lt;p&gt;Since the early times when data begun to be used to compute values, there has always been a need to store complex data in such a way that they would always be easy to access. In ancient times this was accomplished with sine tables and a 98-column multiplication, advances in computing technology has impacted the way data is stored and retrieved.&lt;br&gt;
In the early years of computer technology, processing input/output was particularly slow and would consume more resource and time. To solve this problem, it made sense to reduce significantly the process of reading operations and operations data. A very efficient method that was introduced to solve this problem was &lt;strong&gt;Caching&lt;/strong&gt; (which involves storing data so that it can be available for future request at faster speeds due to an earlier computation of the data stored elsewhere).&lt;br&gt;
However, while systemwide caching tries to automate the process of fetching commonly occurring data items, to enable a much faster mechanism for obtaining data items that possess a sort of immutability, lookup tables were introduced.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  What is a Lookup Table
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;As if defined in computer science, [&lt;a href="https://en.wikipedia.org/wiki/Lookup_table" rel="noopener noreferrer"&gt;1&lt;/a&gt;]&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a lookup table(LUT) is an array that replaces runtime computation with a simpler array indexing operation. This process of utilizing array indexing to compute the running phase of a program is also known as direct addressing. It is much faster and less expensive since data is retrieved from memory using indexes as reference compared to the processing input/output approach. The tables may be pre-calculated and stored in static program storage, calculated (or "pre-fetched") as part of a program's initialization phase, or even stored in hardware in application-specific platforms.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A lookup table is more efficient in terms of lookup operation and has a guaranteed O(1) time complexity. However, it is not possible for two entities to have the same lookup key k, and as the size of the datasets grow increasingly larger, in the magnitude of considering all forms of allottable data, it becomes less practical to stored a LUT in memory.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Address Lookup Table (ALTs)
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;As defined on the Solana documentation, [&lt;a href="https://docs.solana.com/developing/lookup-tables" rel="noopener noreferrer"&gt;2&lt;/a&gt;]&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An address Lookup Tables, commonly referred to as "lookup tables" or "ALTs" for short, allow developers to create a collection of related addresses to efficiently load more addresses in a single transaction. Since each transaction on the Solana blockchain requires a listing of every address that is interacted with as part of the transaction; without ALTs, this listing would effectively be capped at 32 addresses per transaction, but with ALTs, it would be effectively raise the addresses per transaction to 256&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ALTs are part of additional functionalities that were introduced in the versioned transaction format which is quite similar to the legacy transaction format with just slight differences in libraries used. &lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  How to Create An Address Lookup Table(ALTs)
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;This tutorial is going to show you how you can implement ALTs on your projects and help you see the benefits and advantages they offer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;What We Will Implement in This Tutorial&lt;/strong&gt;
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this Tutorial, we will:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Create and execute a &lt;a href="https://docs.solana.com/proposals/versioned-transactions" rel="noopener noreferrer"&gt;Version 0 (V0)&lt;/a&gt; Transaction&lt;/li&gt;
&lt;li&gt;Create and Populate an Address Lookup Table&lt;/li&gt;
&lt;li&gt;Compare the transaction size of two nearly identical transactions where one would implement a lookup table and the other would not &lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
  
  
  Perquisites:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Intermediate Experience with Typescript/JavaScript&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/ts-node" rel="noopener noreferrer"&gt;ts-node&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;basic or solid experience in running Solana transactions&lt;/li&gt;
&lt;li&gt;all necessary imports including classes from Solana Web3 
library&lt;/li&gt;
&lt;li&gt;create a wallet and fund it with some &lt;strong&gt;devnet&lt;/strong&gt; SOL&lt;/li&gt;
&lt;li&gt; set up API endpoint to connect with the Solana network&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your setup Environment should look similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b2f0mj36qdt14n42nim.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b2f0mj36qdt14n42nim.png" alt=" " width="800" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Steps to Creating ALTs
&lt;/h3&gt;
&lt;/blockquote&gt;
&lt;h5&gt;
  
  
  Executing Versioned Transaction V(0)
&lt;/h5&gt;

&lt;p&gt;To use Lookup Tables, you must execute a versioned transactions. &lt;/p&gt;

&lt;p&gt;We can do this by Let's start by creating a new function, &lt;strong&gt;createAndSendV0Tx&lt;/strong&gt;, that accepts an array of TransactionInstructions, &lt;strong&gt;txInstructions&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function createAndSendV0Tx(txInstructions: TransactionInstruction[]) {
// Step 1 - Fetch Latest Blockhash   
let latestBlockhash =await SOLANA_CONNECTION.getLatestBlockhash('finalized');    console.log("   ✅ - Fetched latest blockhash. Last valid height:", latestBlockhash.lastValidBlockHeight)
;    

// Step 2 - Generate Transaction Message    
const messageV0 = new TransactionMessage({ payerKey: SIGNER_WALLET.publicKey,  recentBlockhash: latestBlockhash.blockhash, instructions: txInstructions    }).compileToV0Message();    console.log("   ✅ - Compiled transaction message");    
const transaction = new VersionedTransaction(messageV0);    
// Step 3 - Sign your transaction with the required `Signers`    transaction.sign([SIGNER_WALLET]);    console.log("   ✅ - Transaction Signed");    // Step 4 - Send our v0 transaction to the cluster    const txid = await SOLANA_CONNECTION.sendTransaction(transaction, { maxRetries: 5 });    console.log("   ✅ - Transaction sent to network");    
// Step 5 - Confirm Transaction     
const confirmation = await SOLANA_CONNECTION.confirmTransaction({signature: txid,        blockhash: latestBlockhash.blockhash, lastValidBlockHeight: latestBlockhash.lastValidBlockHeight    });  if (confirmation.value.err) { throw new Error("   ❌ - Transaction not confirmed.") }    console.log('🎉 Transaction succesfully confirmed!', '\n', `https://explorer.solana.com/tx/${txid}?cluster=devnet`);}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's walk through our code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; We fetch the latest blockhash from the network. Note: We pass the parameter, 'finalized', to make sure the block does not belong to a dropped fork.&lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; Using our txInstructions parameter and the latestBlockhash, we create a new MessageV0 by building a Message and executing the .compileToV0Message() method.&lt;br&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; We sign the transaction with an array of signers. In this case, it is just our SIGNER_WALLET.&lt;br&gt;
&lt;strong&gt;Step 4:&lt;/strong&gt; We send the transaction to the cluster using sendTransaction, which will return a transaction signature/id.&lt;br&gt;
&lt;strong&gt;Step 5:&lt;/strong&gt; We wait for the cluster to confirm the transaction has succeeded. If it succeeds, we log our explorer URL; otherwise, we throw an error.&lt;/p&gt;

&lt;p&gt;Once successful with the above, we now move on to create an ALT&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  Create an Address Lookup Table
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;Create a new async function, &lt;strong&gt;createLookupTable&lt;/strong&gt;, that will build our transaction instruction and invoke &lt;strong&gt;createAndSendV0Tx&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function createLookupTable() {
    // Step 1 - Get a lookup table address and create lookup table instruction
    const [lookupTableInst, lookupTableAddress] =
        AddressLookupTableProgram.createLookupTable({
            authority: SIGNER_WALLET.publicKey,
            payer: SIGNER_WALLET.publicKey,
            recentSlot: await SOLANA_CONNECTION.getSlot(),
        });

    // Step 2 - Log Lookup Table Address
    console.log("Lookup Table Address:", lookupTableAddress.toBase58());

    // Step 3 - Generate a transaction and send it to the network
    createAndSendV0Tx([lookupTableInst]);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking down our code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; We create two variables, &lt;strong&gt;lookupTableInst&lt;/strong&gt; and &lt;strong&gt;lookupTableAddress&lt;/strong&gt;, by destructuring the results of the &lt;strong&gt;createLookupTable&lt;/strong&gt; method. This method returns the public key for the table once created and a &lt;strong&gt;TransactionInstruction&lt;/strong&gt; that can be passed into our &lt;strong&gt;createAndSendV0Tx&lt;/strong&gt; function.&lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; We log the table's address &lt;br&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; Finally, we call &lt;strong&gt;createAndSendV0Tx&lt;/strong&gt;by passing &lt;strong&gt;lookupTableInst&lt;/strong&gt; inside of an array to match our type requirements.&lt;/p&gt;

&lt;p&gt;Create an empty address table by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;createLookupTable();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run the transaction, enter your terminal and execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ts-node app.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the transaction has completed, you should receive a URL to the transaction page on Solana Explorer, like in the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xbuoezof9la2x5rmsve.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xbuoezof9la2x5rmsve.png" alt=" " width="672" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The lookup table account address is: &lt;strong&gt;3uBhgRWPTPLfvfqxi4M9eVZC8nS1kDG9XPkdHKgG69nw&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove the call to createLookupTable()&lt;/li&gt;
&lt;li&gt;add the table lookup address from your console to the PublicKey declaration like so :
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const LOOKUP_TABLE_ADDRESS = new PublicKey("YOUR_TABLE_ADDRESS_HERE"); 
// e.g const LOOKUP_TABLE_ADDRESS = new PublicKey("3uBhgRWPTPLfvfqxi4M9eVZC8nS1kDG9XPkdHKgG69nw");

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what's going on with the &lt;strong&gt;extendLookupTable&lt;/strong&gt; method:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We pass our &lt;strong&gt;SIGNER_WALLET&lt;/strong&gt; to pay the transaction fees and any additional rent incurred.&lt;/li&gt;
&lt;li&gt;We define our update authority - in our case, we set that as the &lt;strong&gt;SIGNER_WALLET&lt;/strong&gt; in our table creation step above.&lt;/li&gt;
&lt;li&gt;We pass in the lookup table account address (which we defined as &lt;strong&gt;LOOKUP_TABLE_ADDRESS&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;We pass an array of addresses into our lookup table. We will pass in a few random public keys, but you can pass in any public key that you like! &lt;em&gt;&lt;strong&gt;The Program's "compression" supports storing up to 256 addresses in a single lookup table!&lt;/strong&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;log a link to our lookup table entries for easy access after the transaction is complete. Finally, we pass &lt;strong&gt;TransactionInstruction&lt;/strong&gt; into &lt;strong&gt;createAndSendV0Tx&lt;/strong&gt; to generate a transaction and send it to the network!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Call the new function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;addAddressesToTable();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the in the terminal using the previous &lt;code&gt;ts-node app.ts&lt;/code&gt;command. Check the returned URL to see your transactions and your lookup table entries on the Solana Explorer. On the lookup table entries, there will be a list of all the stored public keys.&lt;/p&gt;

&lt;p&gt;By now perhaps you are asking, &lt;strong&gt;&lt;em&gt;why is this better?&lt;/em&gt;&lt;/strong&gt; Well, The power of ALTs in transaction lies is in the efficiency of the transaction! By effectively &lt;em&gt;&lt;strong&gt;compressing a 32-byte address to a 1-byte index value&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
This is great for speed as well as space efficiency as you can push in more transactions without bothering about space. By eliminating the need for long and complex iterations in cases of numerous addresses, which leads to error-resistance as ALTs can be engineered to prevent duplicate addresses.&lt;br&gt;
Also this is cheaper; by reducing the number and size of the instructions in a transaction, thereby making fees required to develop on the blockchain way more cost-effective. &lt;br&gt;
From transaction caching operations, scalability, speed, cost, the advantages of the address lookup table cannot be overemphasized, the benefits are numerous! &lt;br&gt;
of course they are not the best when it comes to dealing with a dataset of unpredictable large number of possible keys, and could exceed the number of keys that are actually stored. For this sort of cases, hash tables are more efficient. Read more about hash tables &lt;a href="https://wiki.c2.com/?HashTable" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While most use cases of ALTs revolve around transactional caching, decentralized applications employ their power to &lt;em&gt;store&lt;/em&gt; multiple address for easy access at &lt;strong&gt;O(1)&lt;/strong&gt; time; within a single transaction, you can load a large number of addresses&lt;/p&gt;

&lt;p&gt;A very practical use case for ALTs can be found in asset management dApps where multiple wallets are being monitored; without Solana ALTs, it would be a resource consuming process. &lt;/p&gt;

&lt;p&gt;For further reference, You can find another simple example to build on the example we have shown already &lt;a href="https://github.com/bigjoefilms/-Address-Lookup-Tables?source=post_page-----eb826a2a732d--------------------------------" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;We have learned the following points in this terse tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In blockchain transactions, the magnitude of addresses used in multi-level transactions can easily scale in magnitude of millions of addresses; hence requiring an efficient means of retrieving transaction data in an O(1) time&lt;/li&gt;
&lt;li&gt;Lookup tables are best for this as they utilize a concept known as &lt;em&gt;&lt;strong&gt;"direct addressing"&lt;/strong&gt;&lt;/em&gt; which  utilizes array indexing to compute the running phase of a program.&lt;/li&gt;
&lt;li&gt;By utilizing Address Lookup Tables, blockchain developers can create a collection of related addresses to efficiently load more addresses in a single transaction; address tables can store up to 256 addresses each. This can however be a limitation in special cases. In addition to stored addresses, address table accounts also tracks various metadata.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
