<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: George K</title>
    <description>The latest articles on DEV Community by George K (@george_k).</description>
    <link>https://dev.to/george_k</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%2F853182%2F2c8f2300-a723-47b2-bfd6-f557d2f984fa.jpeg</url>
      <title>DEV Community: George K</title>
      <link>https://dev.to/george_k</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/george_k"/>
    <language>en</language>
    <item>
      <title>Web3 and User Privacy: Risks and Solutions</title>
      <dc:creator>George K</dc:creator>
      <pubDate>Thu, 11 May 2023 22:06:13 +0000</pubDate>
      <link>https://dev.to/george_k/web3-and-user-privacy-risks-and-solutions-1i12</link>
      <guid>https://dev.to/george_k/web3-and-user-privacy-risks-and-solutions-1i12</guid>
      <description>&lt;p&gt;Web3 is a new way of experiencing the internet that seeks to break away from the traditional web's centralized and controlled nature. Instead of being at the mercy of a few big players who collect our data, Web3 puts data ownership and control back in the hands of the user.&lt;/p&gt;

&lt;p&gt;Let's take a quick trip down memory lane to get a better sense of what Web3 is all about. Web1.0 was the first iteration of the web, where users had little say in the content they consumed. Web2.0, on the other hand, was a game-changer that unlocked user-generated content and paved the way for the age of blogging and social media. However, this also meant that big tech companies gained unprecedented control over our data and online behavior.&lt;/p&gt;

&lt;p&gt;Web3 aims to change all that by creating a more transparent, decentralized, and user-centric internet. To avoid the dangers of centralization and the concentration of sensitive information in a few hands, Web3 relies on decentralized databases and ledgers that are distributed across nodes and accessible to anyone. This ensures that no entity has complete control over our data while also making it much harder for hackers to get their hands on our sensitive information.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Staples of Privacy in Web3
&lt;/h3&gt;

&lt;p&gt;So how is privacy achieved in Web3?&lt;/p&gt;

&lt;p&gt;First and foremost, privacy is a direct outcome of data ownership. When individuals have control over their data, they can choose how and where it is used. This is particularly important in digital marketing and data-sharing situations. According to studies, 79% of consumers are willing to share their data in exchange for rewards. In the Web3 world, brands will need to build direct relationships with consumers by asking them for permission to use their data and providing value in return.&lt;/p&gt;

&lt;p&gt;Decentralized messaging platforms prioritize user privacy by using end-to-end encryption, where only the intended recipients can access message content. Status and Matrix are two examples of such platforms available today. In contrast, traditional messaging services have been criticized for sharing user data with third parties. Decentralized messaging apps, however, are designed with user privacy in mind.&lt;/p&gt;

&lt;p&gt;Finally, there are trustless transactions, made possible by the use of smart contracts, which remove the need for intermediaries like traditional financial institutions. There already exist numerous decentralized applications, or dApps, that utilize smart contracts, as well as DeFi platforms such as Compound and Aave that enable users to lend and borrow cryptocurrencies without relying on traditional financial institutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges and Concerns
&lt;/h3&gt;

&lt;p&gt;On the other hand, some critics are concerned that the transparent nature of public distributed ledgers might be at odds with our privacy. Web3 allows everyone to access data on the blockchain, but this publicity and transparency raise questions about how our privacy will be protected.&lt;/p&gt;

&lt;p&gt;This concern is not the only one raised by Web3 critics. Here are some others:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Issues&lt;/strong&gt;&lt;br&gt;
There are also security challenges that go beyond data privacy. Anonymous transactions on distributed ledgers are vulnerable to smart contract logic hacks and offer little legal protection in case of wrongdoing. Moreover, the lack of central control and access to data could make it more difficult to fight cybercrime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Privacy Risks&lt;/strong&gt;&lt;br&gt;
Another risk is the exposure of personal information in blockchain transactions. Transactions are recorded on the blockchain, which means they can be traced back to their sources. While Web3 promises freedom from profit-seeking corporations, it also comes with potential data privacy risks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cryptocurrency Wallet Cloning&lt;/strong&gt;&lt;br&gt;
Attackers may attempt to steal cryptocurrency wallets by tricking users into revealing their seed phrases or keys. They exploit loopholes in the verification process to gain access to the wallet contents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Personal Data Breaches&lt;/strong&gt;&lt;br&gt;
Despite the security of blockchain technology, users' personal information is still at risk of hacking if stored on centralized servers or if private keys are compromised.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;De-anonymization&lt;/strong&gt;&lt;br&gt;
Users' identities may be exposed through their transaction history and other publicly available information. Researchers have shown how transactions recorded on the blockchain can be linked to individuals, and some DeFi apps have incorporated third-party web services that can access users' Ethereum addresses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Addressing the Privacy Challenges in Web3
&lt;/h3&gt;

&lt;p&gt;Finally, let’s take a brief overview of the ways in which we, the Web3 community, both developers and users, can tackle the data privacy challenges mentioned above. &lt;/p&gt;

&lt;p&gt;An important concept to keep in mind is Privacy by Design, which means thinking about privacy from the very onset of the development process. This involves prioritizing user privacy over data collection and taking steps to safeguard user data throughout the development cycle. Some examples of these steps can include encryption or minimizing the amount of data collected to only what's necessary to provide the service. Developers can also use hash functions to create anonymous identifiers that don't reveal the users' identities.&lt;/p&gt;

&lt;p&gt;Decentralized Identity or DID solutions, such as the open-source DID protocol and Verifiable Credentials, can give users more control over their digital identities while also maintaining privacy. Unlike traditional identity management systems that require users to give their personal information to centralized authorities (e.g. governments, corporations, or social media platforms) DID solutions allow users to store their personal data on decentralized networks. This way, users have complete authority over who can access and use their data.&lt;/p&gt;

&lt;p&gt;Zero-knowledge proofs are also important for maintaining privacy.  ZKPs allow users to prove that they possess certain information without revealing the information itself. Here's how it works: a verifier requests that a prover perform a specific set of actions that can only be completed if the prover has the necessary information. This is vital for privacy because it allows users to verify their identity without giving away any sensitive information. Essentially, ZKPs provide a way for users to keep their personal information under their full control.&lt;/p&gt;

&lt;p&gt;Privacy coins and networks also offer increased privacy and anonymity to their users. Unlike traditional cryptocurrencies, privacy coins use various techniques to obfuscate transaction data and protect user privacy. For instance, ring signatures are a way for users to sign a transaction on behalf of a group without revealing the specific signer. This makes it difficult to identify the sender or recipient of a transaction, even though the transaction is still recorded on the blockchain. In addition, some privacy coins use stealth addresses, which generate unique, one-time addresses for each transaction. Privacy-focused networks use methods such as encrypted messaging, IP obfuscation, and onion routing to encrypt the user's traffic and allow them to remain anonymous while browsing the internet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;As the expert community keeps working on Web3 privacy solutions, it's essential to remember that users play a big role in protecting their own data and privacy. That's why it's so important to educate users and increase their awareness of security challenges in the Web3 world, along with the steps they can take to address them. I truly hope this article has achieved that goal by providing an overview of Web3 risks and the best practices for maintaining strong privacy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;MakeUseOf, 6 Reasons Web 3.0 Won’t Solve Your Privacy Problems by Adaeze Uche, &lt;a href="https://www.makeuseof.com/reasons-web3-wont-solve-privacy-problems/"&gt;https://www.makeuseof.com/reasons-web3-wont-solve-privacy-problems/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Forbes, Web3 Businesses Have Major Data Privacy Challenges Ahead by Jamilia Grier, &lt;a href="https://www.forbes.com/sites/forbestechcouncil/2023/02/22/web3-businesses-have-major-data-privacy-challenges-ahead/?sh=50d2a6eb1485"&gt;https://www.forbes.com/sites/forbestechcouncil/2023/02/22/web3-businesses-have-major-data-privacy-challenges-ahead/?sh=50d2a6eb1485&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;ByteBao Insights, Building Compliant Web3 Platforms: A Guide to Privacy by Design and Compliance Frameworks, &lt;a href="https://www.bytebao.io/blog/building-compliant-web3-platforms-a-guide-to-privacy-by-design-and-compliance-frameworks"&gt;https://www.bytebao.io/blog/building-compliant-web3-platforms-a-guide-to-privacy-by-design-and-compliance-frameworks&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;TechMonitor, The privacy dangers of web3 and DeFi – and the projects trying to fix them by Claudia Glover, &lt;a href="https://techmonitor.ai/policy/privacy-and-data-protection/web3-defi-privacy"&gt;https://techmonitor.ai/policy/privacy-and-data-protection/web3-defi-privacy&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;101 Blockchains, Know The Risks Of Web 3.0 by Georgia Weston, &lt;a href="https://101blockchains.com/web3-risks/"&gt;https://101blockchains.com/web3-risks/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Permission Blog, What Does Privacy Look Like in Web 3.0? by Charlie Silver, &lt;a href="https://permission.io/blog/data-privacy-in-web-3"&gt;https://permission.io/blog/data-privacy-in-web-3&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;SciencesPo, The Web3 Series: Is Decentralisation The Key to Digital Privacy? &lt;a href="https://www.sciencespo.fr/en/news/the-web3-series-is-decentralisation-the-key-to-digital-privacy"&gt;https://www.sciencespo.fr/en/news/the-web3-series-is-decentralisation-the-key-to-digital-privacy&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Forbes, Web3 Will Change Privacy As We Know It by Nav Dhunay, &lt;a href="https://www.forbes.com/sites/forbestechcouncil/2022/11/09/web3-will-change-privacy-as-we-know-it/?sh=4906bbc74025"&gt;https://www.forbes.com/sites/forbestechcouncil/2022/11/09/web3-will-change-privacy-as-we-know-it/?sh=4906bbc74025&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;TechNode Global, The Promising Impact of Web3 on Data Privacy and Security by Yan Lee, &lt;a href="https://technode.global/2022/10/03/the-promising-impact-of-web3-on-data-privacy-and-security/"&gt;https://technode.global/2022/10/03/the-promising-impact-of-web3-on-data-privacy-and-security/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Medium, How Web3 Protects its Users Data and Privacy by William Awe, &lt;a href="https://medium.com/coinmonks/how-web3-protects-its-users-data-and-privacy-edbc145d1356"&gt;https://medium.com/coinmonks/how-web3-protects-its-users-data-and-privacy-edbc145d1356&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;ByteBao Insights, Web3 Promises Transparency, But Should You Still Worry About Data Privacy? ​​&lt;a href="https://www.bytebao.io/blog/web3-promises-transparency-but-should-you-still-worry-about-data-privacy"&gt;https://www.bytebao.io/blog/web3-promises-transparency-but-should-you-still-worry-about-data-privacy&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Blockster, Web3 Privacy: Protecting Your Data In The Evolving Web3 Landscape, &lt;a href="https://blockster.com/web3-privacy-protecting-your-data-in-the-evolving-web3-landscape"&gt;https://blockster.com/web3-privacy-protecting-your-data-in-the-evolving-web3-landscape&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;ZeroTrust, Web 3.0 security risks: What you need to know by Jessica Groopman, &lt;a href="https://www.techtarget.com/searchsecurity/tip/Top-3-Web3-security-and-business-risks"&gt;https://www.techtarget.com/searchsecurity/tip/Top-3-Web3-security-and-business-risks&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Smart Contract Security: Vulnerabilities and Best Practices</title>
      <dc:creator>George K</dc:creator>
      <pubDate>Sat, 06 May 2023 23:33:43 +0000</pubDate>
      <link>https://dev.to/george_k/smart-contract-security-vulnerabilities-and-best-practices-2jp5</link>
      <guid>https://dev.to/george_k/smart-contract-security-vulnerabilities-and-best-practices-2jp5</guid>
      <description>&lt;h3&gt;
  
  
  Smart Contracts Explained
&lt;/h3&gt;

&lt;p&gt;A smart contract is a type of code that is designed to be executed on a blockchain and enforce the terms of an agreement between parties. Depending on the terms of each specific agreement, this can involve exchanging assets or other types of transactions. By running on a blockchain, a smart contract ensures that transactions are autonomously and accurately executed. &lt;/p&gt;

&lt;p&gt;There are many blockchain platforms that support smart contracts — Ethereum, Hyperledger Fabric,  Binance Smart Chain, and Corda to name but a few. Each blockchain can implement smart contracts differently. For example, the Solidity programming language is utilized to create smart contracts on Ethereum networks.&lt;/p&gt;

&lt;p&gt;It is safe to say that smart contracts is a very promising technology that has all the potential to transform the way we do business. Here’s why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Smart contracts have a wide range of applications.&lt;/strong&gt; There's a variety of use cases for smart contracts, not only in the financial sector but also in other industries. For example, smart contracts can be used to handle supply chain management, real estate transactions, and even voting. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Smart contracts are decentralized.&lt;/strong&gt; They are specifically designed to automate the execution of transactions and other business processes without the need for intermediaries. This reduces associated expenses since there’s no longer any need for costly middlemen, such as lawyers, banks, or brokers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Smart contracts are immutable.&lt;/strong&gt; This means that once they are deployed on the blockchain network, they cannot be modified. As a result, transactions are made fully transparent and traceable, preventing any unauthorized alterations for illicit gain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Smart contracts are secure.&lt;/strong&gt; Participants can be assured that the contract will be executed only if all the conditions and requirements are met.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Smart contracts power NFTs, DeFi, and Web3 platforms, which hold billions of dollars in digital assets. It's crucial to prioritize the security of smart contracts to avoid financial losses and damage to platform reputation resulting from any breaches or attacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Risks
&lt;/h3&gt;

&lt;p&gt;In many ways, what is considered to be an advantage of smart contracts, can also become a source of security issues. As mentioned before, smart contracts are immutable — once a smart contract is deployed, it cannot be modified or updated. This means that if any vulnerabilities or errors are identified in the code after deployment, it can be extremely difficult, if not impossible, to fix.&lt;/p&gt;

&lt;p&gt;Generally smart contract security risks can result from either vulnerabilities in the blockchain itself or coding errors.&lt;/p&gt;

&lt;p&gt;For instance, frontrunning attacks exploit how blockchain processes transactions. Scammers can buy a significant amount of tokens in response to big transactions that will boost the token's price. They then add a higher fee than the big transaction they're targeting to ensure their transaction is processed first. Once the big transaction changes the token's price, they sell the tokens they purchased for a profit.&lt;/p&gt;

&lt;p&gt;Smart contracts can also face security risks from 51% attacks on the underlying blockchain network. This kind of attack happens when an attacker has control over the majority of the network's computing power. This gives them the ability to manipulate the network and create fraudulent transactions, which can result in stolen digital assets from smart contracts or the contracts themselves getting modified.&lt;/p&gt;

&lt;p&gt;As for coding errors, let’s look at why they might occur in the first place. The primary reason is complexity. Smart contracts are extremely intricate to design, develop, and test. Additionally, they are created using specific programming languages, e.g. Solidity. This is a relatively new programming language, and developers may not be fully familiar with its syntax and rules. This can result in coding errors that can be exploited by attackers. Since any blockchain user can access a smart contract, its possible vulnerabilities are also visible throughout the network, and it is not always possible to eliminate them due to immutability.&lt;/p&gt;

&lt;p&gt;Here are some possible vulnerabilities that result from errors in code: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reentrancy vulnerabilities:&lt;/strong&gt; This vulnerability occurs when an attacker repeatedly calls a function before the first invocation finishes, enabling them to withdraw balances multiple times until their balance is reduced to 0. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Over/Under Flows:&lt;/strong&gt; When an integer variable attempts to store an integer above or below its accepted values, vulnerabilities such as overflow or underflow can occur. These vulnerabilities can create unexpected logic flows and enable attackers to exploit the smart contract.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recursive calling:&lt;/strong&gt; This happens when a smart contract calls another external contract before the changes are confirmed, and the external contract may then interact with the initial smart contract recursively in an unauthorized manner as its balance has not yet been updated.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Best Practices
&lt;/h3&gt;

&lt;p&gt;Now, let's discuss some security best practices that can help mitigate the vulnerabilities we've outlined above. &lt;/p&gt;

&lt;h4&gt;
  
  
  1. Design and Architecture
&lt;/h4&gt;

&lt;p&gt;This is one of the staples in smart contract security. Use modular and reusable code, proven design patterns, trusted libraries and frameworks, or open-source tools. OpenZeppelin and ConsenSys are two popular time- and community-tested frameworks that provide a range of secure smart contract templates. Open-source libraries are useful for the same reasons — they have been audited by many developers and are less likely to contain vulnerabilities.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Testing and Code Quality
&lt;/h4&gt;

&lt;p&gt;There are many industry-standard testing frameworks and tools that can help to identify vulnerabilities before they become a problem. For example, the Solidity compiler provides built-in security checks such as integer overflow and underflow protection.&lt;/p&gt;

&lt;p&gt;Penetration testing can also help to identify weaknesses in your smart contract's design. This can be done manually or using automated tools such as fuzz testers. Fuzz testers generate random inputs to the smart contract to test for unexpected behavior and help to uncover vulnerabilities that other testing methods couldn’t detect.&lt;/p&gt;

&lt;p&gt;Test the smart contract on a testnet before deploying to the mainnet. Testnets are blockchain networks used specifically for testing purposes and do not contain real digital assets. &lt;/p&gt;

&lt;p&gt;Finally, conduct regular code reviews to check for vulnerabilities such as reentrancy, overflow/underflow, unchecked return values, and unprotected functions.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Access Control and Authorization
&lt;/h4&gt;

&lt;p&gt;Make sure that only authorized parties should be able to access and modify your contract. The two key access control mechanisms are role-based access control (RBAC) and permissioned access. RBAC allows you to define roles and assign permissions to those roles. Permissioned access can be used to restrict access to your smart contract based on the user's identity.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Auditing and Certification
&lt;/h4&gt;

&lt;p&gt;Smart contracts should be inspected by independent security auditors who cover all aspects, including the code, architecture, and business logic.  Certification from reputable auditing firms can provide additional assurance that the smart contract is secure.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Multi-Signature Wallets
&lt;/h4&gt;

&lt;p&gt;Multi-signature wallets require more than one person to approve a transaction or contract upgrade before it is executed. This provides an additional layer of security, as it ensures that no single person can make changes to the contract without the approval of others.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Timelocks
&lt;/h4&gt;

&lt;p&gt;Timelocks can be used to prevent unauthorized access to digital assets and are commonly used in DeFi applications. A timelock can delay the transaction — e.g. the withdrawal of funds — until a certain period of time has passed. In the case of a security breach, it gives the owner of the smart contract time to respond before any damage is done.&lt;/p&gt;

&lt;h4&gt;
  
  
  7. Bug Bounty
&lt;/h4&gt;

&lt;p&gt;A bug bounty program was created to incentivize ethical hackers to identify and report security flaws in a smart contract. By offering rewards for finding vulnerabilities, you can tap into the expertise of the wider community and fix security issues before they are exploited by attackers. &lt;/p&gt;

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

&lt;p&gt;Smart contracts are now a fundamental aspect of the DeFi ecosystem, and as time goes on, they will likely become a vital part of various business operations and everyday activities. As this happens, it's expected that we'll find better ways of ensuring the utmost security of smart contracts. I trust that this article has given you helpful information on how to tackle the vulnerability challenges associated with this technology today.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Lossless.io Blog, Smart Contract Security Audit 101: The Ultimate Guide, &lt;a href="https://lossless.io/smart-contract-security-audit-101-the-ultimate-guide/"&gt;https://lossless.io/smart-contract-security-audit-101-the-ultimate-guide/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Solidity Academy, Best Practices and Standards for Smart Contract Security, &lt;a href="https://medium.com/coinmonks/best-practices-and-standards-for-smart-contract-security-2cc9643aebf1"&gt;https://medium.com/coinmonks/best-practices-and-standards-for-smart-contract-security-2cc9643aebf1&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;CertiK, Smart Contract Security: Protecting Digital Assets, &lt;a href="https://certik.medium.com/smart-contract-security-protecting-digital-assets-719da8a6c646"&gt;https://certik.medium.com/smart-contract-security-protecting-digital-assets-719da8a6c646&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Hederra Blog, A Guide to Smart Contract Security, &lt;a href="https://hedera.com/learning/smart-contracts/smart-contract-security#:%7E:text=What%20is%20smart%20contract%20security,transactions%20between%20various%20digital%20assets"&gt;https://hedera.com/learning/smart-contracts/smart-contract-security#:~:text=What%20is%20smart%20contract%20security,transactions%20between%20various%20digital%20assets&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;Forbes, Navigating The Security Challenges Of Smart Contracts by David Balaban, 
&lt;a href="https://www.forbes.com/sites/davidbalaban/2023/02/11/navigating-the-security-challenges-of-smart-contracts/?sh=2f7300864992"&gt;https://www.forbes.com/sites/davidbalaban/2023/02/11/navigating-the-security-challenges-of-smart-contracts/?sh=2f7300864992&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Web Security: Understanding Request Smuggling</title>
      <dc:creator>George K</dc:creator>
      <pubDate>Mon, 01 May 2023 23:20:14 +0000</pubDate>
      <link>https://dev.to/george_k/web-security-understanding-request-smuggling-3jfc</link>
      <guid>https://dev.to/george_k/web-security-understanding-request-smuggling-3jfc</guid>
      <description>&lt;p&gt;In today's interconnected digital world, web application security is of paramount importance. One lesser-known but potent security vulnerability that can compromise your web application is request smuggling.&lt;/p&gt;

&lt;p&gt;Request smuggling is a technique used by attackers to send ambiguous requests to web servers. It enables malicious actors to bypass security mechanisms, exploit internal systems, and launch various attacks. In this post, we'll explore request smuggling in-depth, examine its implications, and discuss strategies to prevent it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Request Smuggling
&lt;/h3&gt;

&lt;p&gt;Request smuggling occurs when an attacker crafts an ambiguous HTTP request that confuses the targeted server, causing it to interpret the request in multiple ways. These requests often involve inconsistencies in how the server and the intermediary (such as a reverse proxy or a load balancer) process the HTTP headers, which can lead to unintended behavior.&lt;/p&gt;

&lt;p&gt;In the context of web3, request smuggling can be used to manipulate interactions with smart contracts or deceive users into making transactions they didn't intend. This could result in financial losses and negatively impact the reputation of the targeted application.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Request Smuggling Works
&lt;/h3&gt;

&lt;p&gt;To better understand how request smuggling works, let's first familiarize ourselves with the fundamental building blocks of an HTTP request. An HTTP request consists of a request line, headers, and a message body. The headers convey metadata about the request, and two key headers — &lt;code&gt;Content-Length&lt;/code&gt; and &lt;code&gt;Transfer-Encoding&lt;/code&gt; —are often manipulated by attackers to create ambiguities in the request.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Content-Length&lt;/code&gt; specifies the size of the message body in bytes, whereas &lt;code&gt;Transfer-Encoding&lt;/code&gt; indicates how the message body has been encoded for transmission. When both headers are present in an HTTP request, they can create confusion between the server and any intermediary components, such as reverse proxies or load balancers, leading to request smuggling.&lt;/p&gt;

&lt;p&gt;A request smuggling attack unfolds in the following manner:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The attacker crafts a specially designed HTTP request containing both &lt;code&gt;Content-Length&lt;/code&gt; and &lt;code&gt;Transfer-Encoding&lt;/code&gt; headers with conflicting values.&lt;/li&gt;
&lt;li&gt;This ambiguous request is sent to the targeted server, which is often fronted by an intermediary component like a reverse proxy or load balancer.&lt;/li&gt;
&lt;li&gt;Due to inconsistencies in how the server and the intermediary process HTTP headers, they interpret the request differently. The server might rely on the &lt;code&gt;Content-Length&lt;/code&gt; header, whereas the intermediary may prioritize the &lt;code&gt;Transfer-Encoding&lt;/code&gt; header.&lt;/li&gt;
&lt;li&gt;Consequently, the server processes the request as a single entity, while the intermediary interprets it as multiple separate requests.&lt;/li&gt;
&lt;li&gt;The smuggled request, which is hidden within the initial request, bypasses the server's security mechanisms and gets executed, potentially causing unauthorized access, data breaches, or other malicious activities.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's consider an example to illustrate request smuggling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /api/submit HTTP/1.1
Host: example.com
Content-Length: 44
Transfer-Encoding: chunked

0

POST /api/smuggled HTTP/1.1
Host: example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the attacker sends an HTTP request containing both &lt;code&gt;Content-Length&lt;/code&gt; and &lt;code&gt;Transfer-Encoding&lt;/code&gt; headers. The server, relying on the Content-Length header, interprets it as a single POST request. However, the intermediary, following the Transfer-Encoding header, processes it as two separate POST requests. As a result, the second POST request ("/api/smuggled") gets smuggled and executed on the server, potentially leading to security breaches or other harmful consequences.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preventing Request Smuggling
&lt;/h3&gt;

&lt;p&gt;To protect your web or web3 application from request smuggling, consider the following measures:&lt;/p&gt;

&lt;p&gt;Normalize incoming requests: Ensure that your server and intermediary have a consistent understanding of incoming requests by normalizing them. This may involve removing duplicate headers, converting header names to lowercase, and consistently handling the &lt;code&gt;Content-Length&lt;/code&gt; and Transfer-Encoding headers.&lt;/p&gt;

&lt;p&gt;Update and configure software: Regularly update your server, proxy, and load balancer software to address known vulnerabilities. Configure your server to reject requests with ambiguous headers or those containing both &lt;code&gt;Content-Length&lt;/code&gt; and Transfer-Encoding.&lt;/p&gt;

&lt;p&gt;Implement strict validation: Validate incoming requests to ensure they adhere to the expected format and reject those that don't. Be cautious with user-generated content and always sanitize input before processing it.&lt;/p&gt;

&lt;p&gt;Monitor and log: Implement robust logging and monitoring systems to detect and respond to potential request smuggling attacks. This will help you identify any suspicious activity and take corrective action quickly.&lt;/p&gt;

&lt;p&gt;Perform regular security audits: Conduct regular security audits of your web or web3 application, including penetration testing and code reviews. This will help identify potential vulnerabilities and ensure your application remains secure.&lt;/p&gt;

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

&lt;p&gt;Request smuggling is a significant threat to web applications, and understanding this attack vector is crucial for maintaining a secure environment. By implementing the preventive measures outlined in this post, you can greatly reduce the risk of request smuggling and protect your application from potential attacks.&lt;/p&gt;

</description>
      <category>security</category>
      <category>backend</category>
      <category>web3</category>
    </item>
    <item>
      <title>Embracing Custom Errors in Solidity</title>
      <dc:creator>George K</dc:creator>
      <pubDate>Sun, 23 Apr 2023 14:09:59 +0000</pubDate>
      <link>https://dev.to/george_k/embracing-custom-errors-in-solidity-55p8</link>
      <guid>https://dev.to/george_k/embracing-custom-errors-in-solidity-55p8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Solidity, the smart contract programming language for the Ethereum blockchain, has always had a way to handle errors and exceptions. The default error handling mechanism, through &lt;code&gt;require&lt;/code&gt;, &lt;code&gt;assert&lt;/code&gt;, and &lt;code&gt;revert&lt;/code&gt; functions, allowed developers to manage exceptions and halt the execution of contracts if specific conditions were not met. However, these default errors lacked the flexibility and expressiveness that developers needed for building robust and complex smart contract systems.&lt;/p&gt;

&lt;p&gt;With the introduction of custom errors in Solidity 0.8.4, developers now have a more powerful tool for managing exceptions and crafting more informative error messages, making debugging and troubleshooting easier. This article will explore the benefits of custom errors in Solidity, as well as provide examples and insights on how to effectively use them in your smart contracts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Errors in Solidity
&lt;/h2&gt;

&lt;p&gt;Basic errors in Solidity are simple and straightforward. They can be triggered using the &lt;code&gt;require&lt;/code&gt; or &lt;code&gt;revert&lt;/code&gt; functions, which take a string argument as an error message. For example, consider the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;buyTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Amount must be greater than zero"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Token purchase logic
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;require&lt;/code&gt; function checks if the amount is greater than zero. If not, the function call will be reverted, and the specified error message will be returned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Errors in Solidity 0.8.4
&lt;/h2&gt;

&lt;p&gt;Solidity 0.8.4 introduced custom errors, allowing developers to define their own error types with specific error codes and parameters. This new feature enhances error handling by providing more context and information about the reason for the error. Custom errors can be declared using the &lt;code&gt;error&lt;/code&gt; keyword, followed by the error name and an optional list of parameters.&lt;/p&gt;

&lt;p&gt;A simple custom error without parameters can be declared as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="n"&gt;InsufficientFunds&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;revert&lt;/span&gt; &lt;span class="n"&gt;InsufficientFunds&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Withdrawal logic
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the custom error &lt;code&gt;InsufficientFunds&lt;/code&gt; is defined and used to replace the default error message in the &lt;code&gt;require&lt;/code&gt; statement. This makes the error handling code more concise and easier to understand.&lt;/p&gt;

&lt;p&gt;A more complex custom error with parameters can be declared and used like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;maximumTransfer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="n"&gt;InvalidAmount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;requested&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;maximum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;transferTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;maximumTransfer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;revert&lt;/span&gt; &lt;span class="n"&gt;InvalidAmount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maximumTransfer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Token transfer logic
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the custom error &lt;code&gt;InvalidAmount&lt;/code&gt; takes two parameters: &lt;code&gt;requested&lt;/code&gt; and &lt;code&gt;maximum&lt;/code&gt;. When the error is triggered, it provides additional information about the invalid amount, making it easier for developers to identify the issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try/Catch Mechanism in Solidity
&lt;/h2&gt;

&lt;p&gt;Solidity also provides a try/catch mechanism to handle errors and exceptions gracefully. This allows developers to write more robust and fault-tolerant smart contracts by catching and handling errors within the contract's execution.&lt;/p&gt;

&lt;p&gt;Combining custom errors with the try/catch mechanism allows for more granular error handling. Here's an example of using custom errors with try/catch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;executeTransfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="n"&gt;tokenContract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;transferTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Successful transfer
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;bytes4&lt;/span&gt; &lt;span class="n"&gt;errorSelector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bytes4&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="c1"&gt;// Assuming there are InvalidAmount and InsufficientFunds errors defined
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errorSelector&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;InvalidAmount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Handle invalid amount error
&lt;/span&gt;        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errorSelector&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;InsufficientFunds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Handle insufficient funds error
&lt;/span&gt;        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Handle other errors
&lt;/span&gt;        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this revised example, the try/catch statement catches the low-level bytes memory reason returned by the failing function call. We then decode the error selector and use conditional logic to handle the error based on its selector.&lt;/p&gt;

&lt;p&gt;It is important to note that custom errors can be spoofed when interacting with untrusted contracts. If your contract calls another contract that you do not control, be cautious when relying on the parsed error type. Malicious contracts could deliberately return custom error data that mimics the expected error format, potentially leading to incorrect error handling or other unintended consequences. In such cases, it is essential to implement additional security measures and verify the authenticity of the error data before proceeding with any error handling logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parsing Custom Errors on the Client Side
&lt;/h2&gt;

&lt;p&gt;When interacting with a smart contract from a client-side application, you can also parse custom errors manually. Here's an example using JavaScript and the ethers.js library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokenContract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenABI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tokenContract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transferTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reasonBytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorSelector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hexDataSlice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reasonBytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;invalidAmountSelector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tokenContract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getSighash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;InvalidAmount(uint256,uint256)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;insufficientFundsSelector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tokenContract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getSighash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;InsufficientFunds()&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorSelector&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;invalidAmountSelector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid amount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorSelector&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;insufficientFundsSelector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Insufficient funds for the transfer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unknown error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we use the ethers.js library to interact with the token contract. When an error is encountered, we extract the error selector from the error data and use it to determine the type of error that occurred.&lt;/p&gt;

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

&lt;p&gt;Custom errors in Solidity provide developers with a more powerful and expressive tool for managing exceptions in their smart contracts. By combining custom errors with the try/catch mechanism in Solidity and parsing them on the client side, developers can build more robust and fault-tolerant applications that are easier to debug and maintain. Embrace custom errors in your smart contracts to improve the overall development experience and the quality of your code.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using AsyncLocalStorage in Node.js: Real-World Use Cases</title>
      <dc:creator>George K</dc:creator>
      <pubDate>Tue, 14 Mar 2023 17:13:48 +0000</pubDate>
      <link>https://dev.to/george_k/using-asynclocalstorage-in-nodejs-real-world-use-cases-3ekd</link>
      <guid>https://dev.to/george_k/using-asynclocalstorage-in-nodejs-real-world-use-cases-3ekd</guid>
      <description>&lt;p&gt;In modern web applications, many operations happen asynchronously. Whether it's fetching data from a remote server, performing a complex database query, or handling an incoming request, your code needs to work with asynchronous operations effectively. However, asynchronous code can be challenging to manage, especially when you need to share context across different parts of your application. AsyncLocalStorage is a powerful tool that helps you manage context across asynchronous operations. In this article, we will explore AsyncLocalStorage and learn how to use it in your Node.js applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Asynchronous programming is a fundamental concept in modern web development. Asynchronous programming is all about performing tasks that don't block the main thread of execution. Asynchronous operations are crucial for building high-performance applications that can handle many concurrent requests. However, asynchronous programming can be tricky to manage, especially when you need to share context across different parts of your application. For example, you may need to pass user information, tracing information, or transaction objects across asynchronous operations.&lt;/p&gt;

&lt;p&gt;AsyncLocalStorage is a new Node.js API that provides a way to store and retrieve data across asynchronous operations. AsyncLocalStorage allows you to create a context that is available to all the asynchronous operations executed within that context. You can use this context to store data that needs to be shared across different parts of your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 1: Tracing and Logging
&lt;/h2&gt;

&lt;p&gt;One common use case for AsyncLocalStorage is tracing and logging. When an error occurs, it's essential to have all the relevant information available to debug the issue quickly. One way to achieve this is to pass a unique identifier (traceId) to all the logs generated during a request's lifecycle. With AsyncLocalStorage, you can store the traceId and retrieve it whenever you need it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// logging.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AsyncLocalStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;async_hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;asyncLocalStorage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AsyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;withTraceId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;traceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;asyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;traceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;traceId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;asyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getStore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; traceId=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;traceId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// app.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;withTraceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./logging&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;traceId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x-trace-id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;withTraceId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;traceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`processing request &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/post/:postId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetchPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`fetching data for post id: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// some logic to fetch post&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Hello world, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code defines an asynchronous middleware function &lt;code&gt;authMiddleware&lt;/code&gt; that authenticates and stores the resulting user object using asyncLocalStorage. And &lt;code&gt;getUserSecret&lt;/code&gt; uses &lt;code&gt;getCurrentUser&lt;/code&gt; to retrieve the current user and then performs some asynchronous operation to fetch data for the user.&lt;/p&gt;

&lt;p&gt;AsyncLocalStorage can be used to pass other tags or metadata through to logs as well, not just trace IDs. This can be helpful for tracking other information relevant to a particular request or context, such as user IDs, session IDs, or any other relevant data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 2: Authentication
&lt;/h2&gt;

&lt;p&gt;Another use case for AsyncLocalStorage is authentication. When a user logs in, you need to store the user's information somewhere so that you can access it across different parts of your application. With AsyncLocalStorage, you can store the user's information and retrieve it whenever you need it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// auth.js&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// fetch user data with authToken&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;john&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;authMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x-auth-token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;authToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authToken&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;asyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getCurrentUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;asyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// secret.js&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUserSecret&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getCurrentUser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// some async operation to fetch data for user.id&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`secret of &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// app.js&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authMiddleware&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/secret&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getCurrentUser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unauthorized&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getUserSecret&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach eliminates the need to pass the user object explicitly through function parameters, making the code more concise and easier to read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 3: Transactions
&lt;/h2&gt;

&lt;p&gt;When you work with databases, you sometimes need to execute multiple queries within a single transaction. However, passing the transaction object explicitly can be non-trivial, especially when you have multiple queries executed in different code places. With AsyncLocalStorage, you can store the transaction object and retrieve it whenever you need it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AsyncLocalStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;async_hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;knex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Knex&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;knex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// database.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;knex&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// database configuration&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;asyncLocalStorage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AsyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;withTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;asyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getCurrentTransaction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;asyncLocalStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getStore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trx&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Knex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Transaction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// task.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getTask&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getCurrentTransaction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;trx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tasks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;forUpdate&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;skipLocked&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;completeTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getCurrentTransaction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;trx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tasks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// worker.ts&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;work&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;withTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getTask&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// do some work&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;completeTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;withTransaction&lt;/code&gt; function creates a transaction using the knex library and runs the provided function with the transaction context.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;getTask&lt;/code&gt; and &lt;code&gt;completeTask&lt;/code&gt; functions retrieve and update a task from the database using the transaction from &lt;code&gt;getCurrentTransaction&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, the work function uses &lt;code&gt;withTransaction&lt;/code&gt; to execute the getTask and completeTask functions within a transaction.&lt;/p&gt;

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

&lt;p&gt;AsyncLocalStorage is a powerful tool that allows you to manage context across asynchronous operations. You can use AsyncLocalStorage to store and retrieve data that needs to be shared across different parts of your application. However, AsyncLocalStorage should be used with caution, and you should be aware of its limitations. In some cases, it's better to pass data explicitly, especially in simple applications where passing the context as a parameter is easy.&lt;/p&gt;

&lt;p&gt;In conclusion, AsyncLocalStorage is a great tool that you should consider when you need to share context across asynchronous operations. Whether you're working with tracing information, user data, or transaction objects, AsyncLocalStorage can help you manage your context effectively.&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>DNS spoofing</title>
      <dc:creator>George K</dc:creator>
      <pubDate>Tue, 30 Aug 2022 16:40:48 +0000</pubDate>
      <link>https://dev.to/george_k/dns-spoofing-5h8a</link>
      <guid>https://dev.to/george_k/dns-spoofing-5h8a</guid>
      <description>&lt;p&gt;To send a request to any service or device on the Internet you need to know its IP-address. IP-addresses are not human-friendly but thanks to DNS today we can use human-readable “addresses” like google.com – we call them domains. When you type “google.com” in a browser your OS sends a query to a DNS resolver to get IP-address for that domain underneath. And DNS resolver sends query to a Authoritative nameserver to get that information.&lt;/p&gt;

&lt;p&gt;To speed up and optimize that process DNS resolvers usually cache responses from Authoritative nameservers (normally for a period specified by “TTL” in the DNS record). Next time someone queries “google.com” DNS resolver will take that data from cache unless cache is empty or expired. &lt;/p&gt;

&lt;p&gt;Okay, everything looks good so far. All works, users are able to open google.com without any delays.&lt;/p&gt;

&lt;h3&gt;
  
  
  DNS Spoofing
&lt;/h3&gt;

&lt;p&gt;With DNS spoofing (also known as DNS cache poisoning) it’s possible to “put” incorrect IP-address for some domain into DNS Resolver cache. And that DNS Resolver will respond to queries with incorrect IP-address for the domain until cache is expired. With that attacker may lead users to malicious website. And the website may try to steal data or money from unsuspecting users.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does it work
&lt;/h3&gt;

&lt;p&gt;DNS Resolvers and nameservers use UDP to send requests and responses. Unlike TCP, UDP doesn’t use “handshakes” to initiate connection, doesn’t check if recipient is ready to receive and doesn’t validate if response came from legitimate sender. That is, attacker can send message to a DNS Resolver pretending to be a legitimate server responding to a query:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attacker queries “&lt;em&gt;example.com&lt;/em&gt;” from DNS Resolver&lt;/li&gt;
&lt;li&gt;And at the same time sends forged response to the DNS Resolver like “IP-address for example.com is 1.2.3.4” (where 1.2.3.4 is IP-address of malicious website)&lt;/li&gt;
&lt;li&gt;If DNS Resolver receives attacker’s message first it will cache forged data – resolver can’t validate for sure if that message came from Authoritative nameserver&lt;/li&gt;
&lt;li&gt;Next time someone queries “&lt;em&gt;example.com&lt;/em&gt;” DNS Resolver will respond with forged data – “IP-address for example.com is 1.2.3.4”&lt;/li&gt;
&lt;li&gt;And that someone may open malicious website in browser&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DNS Spoofing difficulties
&lt;/h3&gt;

&lt;p&gt;Despite this vulnerability of DNS caching process DNS spoofing attacks are not easy. The DNS Resolver does actually query the Authoritative nameserver, so attacker has only a few milliseconds to send the fake reply before the real reply arrives. Moreover attacker may need to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UDP port – many DNS Resolvers use random port for additional security&lt;/li&gt;
&lt;li&gt;Request id&lt;/li&gt;
&lt;li&gt;If DNS Resolver caches that specific query at all&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the other hand attacker may gain access to DNS Resolver itself (or owner of the resolver may be malicious actor himself). In that case cached data can be easily forged.&lt;/p&gt;

&lt;p&gt;The risk of DNS cache poisoning is real. &lt;/p&gt;

&lt;h3&gt;
  
  
  SSL and HSTS
&lt;/h3&gt;

&lt;p&gt;That attack is partially mitigated by SSL. Malicious actors can’t generate SSL-certificate without access to your domain. In case user tries to open &lt;em&gt;example.com&lt;/em&gt; (and &lt;em&gt;example.com&lt;/em&gt; IP-address was received from DNS Resolver with poisoned cache) then any modern browser will show an error and stop user from doing it. However there are cases when users will still open http version of a website:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some of them will try to “fix” that error by changing “https” to “http”&lt;/li&gt;
&lt;li&gt;Some of them may have http version in their bookmarks&lt;/li&gt;
&lt;li&gt;Attacker may share http link e.g. by using fishing emails&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HSTS header (short for HTTP Strict Transport Security) may improve it a bit. That header directs browser to open that website using https only. Meaning if user previously opened &lt;em&gt;example.com&lt;/em&gt; browser won’t let him to use http version. But if user opens website for the first time – he will be able to use http version and malicious website will be opened.&lt;/p&gt;

&lt;h3&gt;
  
  
  DNSSEC
&lt;/h3&gt;

&lt;p&gt;Domain Name System was created without taking much security into account. And that led to such vulnerabilities. DNSSEC (Domain Name System Security Extensions) was created to fill that gap. DNSSEC is a feature of the Domain Name System  that authenticates responses to domain name lookups and guarantees data integrity. It does not provide privacy protection for these lookups, but prevents attackers from poisoning the responses to DNS requests.&lt;/p&gt;

&lt;p&gt;All answers from DNSSEC protected zones are digitally signed using asymmetric key. Meaning it’s possible to check signature of DNS Resolver or Authoritative nameserver response to make sure it wasn’t forged. So in case of the attack described above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attacker queries “&lt;em&gt;example.com&lt;/em&gt;” from DNS Resolver&lt;/li&gt;
&lt;li&gt;And at the same time sends forged response to the DNS Resolver like “IP-address for example.com is 1.2.3.4” (where 1.2.3.4 is IP-address of malicious website)&lt;/li&gt;
&lt;li&gt;If DNS Resolver receives attacker’s message first it will ignore that message because digital signature is not valid&lt;/li&gt;
&lt;li&gt;DNS Resolver then receives response from Authoritative server and caches it&lt;/li&gt;
&lt;li&gt;Attack was unsuccessful &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To use DNSSEC it should be supported by both your TLD and your Domain registrar (or DNS operator that manages DNS records). &lt;/p&gt;

&lt;p&gt;You can check list of TLDs which support DNSSEC here &lt;a href="https://support.openprovider.eu/hc/en-us/articles/216648838-List-of-TLDs-that-support-DNSSEC"&gt;https://support.openprovider.eu/hc/en-us/articles/216648838-List-of-TLDs-that-support-DNSSEC&lt;/a&gt;. If your Domain registrar/DNS operator does not support DNSSEC (or does not support DNSSEC for your TLD) you can move to different registrar or operator. &lt;/p&gt;

&lt;h3&gt;
  
  
  DNS Registrar compromise
&lt;/h3&gt;

&lt;p&gt;Attacker may somehow gain access to your DNS Registrar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your password may be compromised&lt;/li&gt;
&lt;li&gt;Or DNS Registrar may have some security flaws on its side&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In first case common security practices will help to prevent the attack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use strong password&lt;/li&gt;
&lt;li&gt;Keep password in secure place, do not keep it as a plaintext, do not share password, etc&lt;/li&gt;
&lt;li&gt;Use 2FA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In second case you can’t fully protect yourself but you can detect if somebody altered DNS records for your domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  DNS monitoring
&lt;/h3&gt;

&lt;p&gt;If malicious actor changed DNS records of your domain you better get notified about it as soon as possible. You can configure automatic monitoring to check DNS records of your domain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check if specific records have expected values. E.g. if you A record for your domain has expected IP-address&lt;/li&gt;
&lt;li&gt;Check if records were changed. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are services that allow you to set up DNS monitoring.&lt;/p&gt;

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

&lt;p&gt;DNS security is not the first thing the comes to mind when you start thinking about app security. However threats are real and such attacks happen (and sometimes cost users a lot of money &lt;a href="https://rekt.news/curve-finance-rekt/"&gt;https://rekt.news/curve-finance-rekt/&lt;/a&gt;). So it’s better to be protected.&lt;/p&gt;

</description>
      <category>security</category>
      <category>dns</category>
    </item>
    <item>
      <title>Arbitrum Nitro from L2 dApps developer perspective</title>
      <dc:creator>George K</dc:creator>
      <pubDate>Wed, 24 Aug 2022 06:14:05 +0000</pubDate>
      <link>https://dev.to/george_k/arbitrum-nitro-from-l2-dapps-developer-perspective-4led</link>
      <guid>https://dev.to/george_k/arbitrum-nitro-from-l2-dapps-developer-perspective-4led</guid>
      <description>&lt;h3&gt;
  
  
  What are Arbitrum and Nitro
&lt;/h3&gt;

&lt;p&gt;Arbitrum is a layer-2 blockchain that uses Optimistic Rollup technology. It works on top of Ethereum and inherits its security. And at the same time cuts transaction costs by multiple times. &lt;/p&gt;

&lt;p&gt;Nitro is the most significant technical upgrade since Arbitrum was launched. It will massively reduce transaction costs and increase network capacity.&lt;/p&gt;

&lt;p&gt;Today Arbitrum’s capacity is throttled, however with Nitro it will be able to up throughput. While Arbitrum today is already 90–95% cheaper than Ethereum on average, Nitro cuts our costs even further. The upgrade is planned for August, 31.&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s new?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Ethereum L1 Gas Compatibility&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Currently Arbitrum has separate Computation and Storage types of gas. With Nitro upgrade gas pricing and accounting for EVM operations will be perfectly in line with L1; no more ArbGas.&lt;/p&gt;

&lt;p&gt;That is L2 gas usage will change. If you have any hard-coded values (either inside smart-contract or off-chain app that sends transactions) you should change these values accordingly. &lt;/p&gt;

&lt;p&gt;In general it's better to avoid hard-coding gas since both the L1 and L2 gas schedule may change in the future.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calldata compression&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Compression takes place protocol level; dApps don't need to change anything, data will just get cheaper and your users will pay less for the same transactions. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frequent Timestamps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Timestamps (accessed via block.timestamp on L2) are updated every block based on the sequencer’s clock, it is no longer linked to the timestamp of the last L1 block.&lt;/p&gt;

&lt;p&gt;Currently each L2 block had timestamp of the the corresponding L1 block. That is multiple blocks have the same timestamp and adjacent blocks might have timestamps with a big difference (e.g. 1 minute) even though they were created within 1 second. That might create some confusion and make debugging a bit harder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lower contract code size limit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arbitrum allows contracts up to 48KB to be deployed. But now only up to 24KB are deployable (as specified in &lt;a href="https://eips.ethereum.org/EIPS/eip-170"&gt;EIP-170&lt;/a&gt;). Previously deployed contracts above the limit will be maintained, however contracts deployed by these legacy contracts are capped by the new size.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Geth tracing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;debug_traceTransaction&lt;/code&gt; RPC endpoint is supported; this includes tracing of ArbOS internal bookkeeping actions.&lt;/p&gt;

&lt;p&gt;Sometimes it’s hard to figure out what exactly happened within some complex transaction with lots of internal transactions. And now with supported &lt;code&gt;debug_traceTransaction &lt;/code&gt; endpoint it’s possible. Right now only Geth supports tracing, Parity will do it in the coming months&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L2 Block hash EVM Consistency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;L2 block hashes take the same format as on Ethereum (if you query it from the ArbSys precompile, not the one in &lt;code&gt;block.hash(uin256)&lt;/code&gt;). &lt;/p&gt;

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

&lt;p&gt;There are also changes related to Layer 1. If your dApp has something to do with e.g. Arbitrum Bridge or it interacts with Aribtrum contracts on Ethereum then you should probably support Nitro on your side.&lt;/p&gt;

&lt;p&gt;You can also find up-to-date list of breaking changes here &lt;a href="https://github.com/OffchainLabs/nitro/blob/master/docs/migration/dapp_migration.md"&gt;https://github.com/OffchainLabs/nitro/blob/master/docs/migration/dapp_migration.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's only one week left before Nitro upgrade. So in case your dApps needs to be updated you better to hurry up.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>arbitrum</category>
    </item>
    <item>
      <title>Web3-frontend security</title>
      <dc:creator>George K</dc:creator>
      <pubDate>Sun, 07 Aug 2022 15:10:47 +0000</pubDate>
      <link>https://dev.to/george_k/web3-frontend-security-1id5</link>
      <guid>https://dev.to/george_k/web3-frontend-security-1id5</guid>
      <description>&lt;p&gt;In the web3 universe, security is of paramount importance, as a lot of money is at stake, and any mistake can lead to great losses. Too many people are in the business of looking for vulnerabilities in projects in order to exploit them. First of all, they look for vulnerabilities in contracts, thus in the market, there are companies that audit them. For some reason, the web3 universe lacks front-end auditors, even though front-end vulnerabilities can also lead to big losses. Here is an example of one of the biggest exploits — &lt;a href="https://www.theblock.co/post/126072/defi-protocol-badgerdao-exploited-for-120-million-in-front-end-attack"&gt;the attackers were able to steal $ 120 million&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By frontend, I mean not only the client-side, but also the server (for example nodejs), that responds to a request from the browser and acts as an intermediary between the browser and the API.&lt;/p&gt;

&lt;p&gt;The frontend for decentralized applications does not introduce new types of vulnerabilities, but some of them may pose a greater threat specifically for web3 projects. For example, Cross-Site Request Forgery (CSRF) may seem not to pose any danger for some types of projects, however it may introduce serious risks for web3 applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cross-site scripting (XSS)
&lt;/h3&gt;

&lt;p&gt;Probably one of the most dangerous vulnerabilities allowing an attacker to execute arbitrary code on a page. In fact, it means getting full access to the web page: one can change its content, send requests on user behalf, read sensitive data, and so on. For example, when a user clicks on the send "transaction button", malicious actor can replace the payload of the transaction so that the user sends their funds to the attacker's wallet.&lt;/p&gt;

&lt;p&gt;Let’s take a closer look. Imagine some app accepts &lt;code&gt;search&lt;/code&gt; parameter in query string and renders page with text "Search results for query: ${search}". If app does not sanitize that param user can pass something like &lt;code&gt;search=&amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;&lt;/code&gt;. And that code will be executed.&lt;/p&gt;

&lt;p&gt;User input can be anything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;query string or data from submitted form (e.g. UI uses some GET parameter to display it on the page);&lt;/li&gt;
&lt;li&gt;user generated content - if users can generate content on the site (e.g. a comment);&lt;/li&gt;
&lt;li&gt;data from localStorage, sessionStorage, cookie.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How to protect:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Never trust user input, always sanitize it&lt;/li&gt;
&lt;li&gt;To reiterate, you can't trust any user input: query string, from data, local and session storages, cookies, IndexedDB, etc&lt;/li&gt;
&lt;li&gt;Client-side frameworks usually sanitize data by default. However, React, for example does not sanitize data used in attributes (i.e. &lt;code&gt;&amp;lt;div data-name={evilUserInput}&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt; can be dangerous)&lt;/li&gt;
&lt;li&gt;Correct Content-Type. An XSS vulnerability can also happen on a server without an html page. For example, the express framework defaults to text/html. And code like &lt;code&gt;if (req.params.option !== "foo") { res.send(Invalid option ${req.params.option}) }&lt;/code&gt; leads to a vulnerability, an attacker can pass &lt;code&gt;?option=&amp;lt;script &amp;gt;alert(1)&amp;lt;/script&amp;gt;&lt;/code&gt; and share this link&lt;/li&gt;
&lt;li&gt;X-XSS-Protection: 0 header. Yes, you need to turn it off, only introduces more risks. If you want to dive into it, read more here &lt;a href="https://stackoverflow.com/a/57802070"&gt;https://stackoverflow.com/a/57802070&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Content-Security-Policy header. Let’s discuss it in more detail.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Content-Security-Policy
&lt;/h3&gt;

&lt;p&gt;With this header, you can struct browser which types of resources cannot be loaded, which can be and how. For example, you can allow &lt;code&gt;.js&lt;/code&gt; scripts to be loaded and executed only from your domain using &lt;code&gt;Content-Security-Policy: script-src self&lt;/code&gt;, in this case all inline scripts on the page will not be executed. &lt;/p&gt;

&lt;p&gt;So even if an attacker can find an XSS vulnerability and insert a malicious script, the code will not be executed and users will be safe. With &lt;code&gt;Content-Security-Policy&lt;/code&gt;, you can allow certain inline scripts if you need. More information about this header &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP"&gt;https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Clickjacking
&lt;/h3&gt;

&lt;p&gt;The main type of attack is when an attacker inserts an invisible iframe with a service on their site. And when clicking on a button, the user actually clicks a button on the service, thus performing some kind of action without realizing it. &lt;/p&gt;

&lt;h4&gt;
  
  
  An attacker can also do the opposite:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;embed a service in your iframe to pretend to be the service itself; &lt;/li&gt;
&lt;li&gt;place a malicious button on top of it with a “bad” transaction that will send money to the attacker;&lt;/li&gt;
&lt;li&gt;it remains to somehow get the user to visit their website (e.g. by using similar domain name and sending phishing emails), the user may not notice that they are using a different website.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How to protect:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Header &lt;code&gt;X-Frame-Options: DENY&lt;/code&gt;. If your service uses iframes, you can specify &lt;code&gt;SAMEORIGIN&lt;/code&gt; or a list of domains where it is allowed to embed an iframe with the service.&lt;/li&gt;
&lt;li&gt;Or you can do the same with &lt;code&gt;Content-Security-Policy: frame-src self&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cross-Site Request Forgery (CSRF)
&lt;/h3&gt;

&lt;p&gt;If your site has authorization, then you may face CSRF. How it works: an attacker on their site can send a request to the your service, where the user is authorized, imperceptibly from the user. Further, they can do some action on behalf of the user.&lt;/p&gt;

&lt;p&gt;For example, send money to someone if the service allows it. For a GET request, this is quite simple, for example, one can insert &lt;code&gt;&amp;lt;img src=“https://mybank.com?transfer.php…” /&amp;gt;&lt;/code&gt;, and send (submit) the form for a POST request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to protect&lt;/strong&gt;: use CSRF tokens. The request for each user action must contain a unique token that only your service knows, thus, the attacker's site cannot access it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other vulnerabilities and best practices
&lt;/h3&gt;

&lt;p&gt;There are other types of attacks that are less common or less likely to lead to large losses. However, it's still good for you to at least know about them and keep in mind that they exist.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DDoS&lt;/strong&gt;. Use services like Cloudflare to protect from DDoS attacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS injection&lt;/strong&gt;. You should protect the website from loading styles from different domains with the “Content-Security-Policy” header.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Referrer leakage&lt;/strong&gt;. In case there is some sensitive data in the URL, it can be leaked when a user goes to another website. Use the “Referrer-Policy” header to instruct browsers to not send the Referrer header.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open redirect&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smuggling requests&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Npm audit&lt;/strong&gt;. Use it to check if packages you use do not have known vulnerabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS&lt;/strong&gt;. Always use HTTPS protocol.&lt;/li&gt;
&lt;li&gt;Do not store sensitive data client-side if possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Instead of conclusion
&lt;/h3&gt;

&lt;p&gt;All in all, it was just an overview, I briefly touched upon the topic of front-end security. For a profound understanding of vulnerabilities and how to fix them, it is not enough. It was just to spark your professional curiosity and a springboard for further reading.&lt;/p&gt;

&lt;p&gt;Good luck with your web3 projects, and, hopefully, this article at least made some of you think about improving your project’s frontend security.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Smart contracts integration testing with hardhat mainnet fork</title>
      <dc:creator>George K</dc:creator>
      <pubDate>Sun, 24 Jul 2022 13:43:38 +0000</pubDate>
      <link>https://dev.to/george_k/smart-contracts-integration-testing-with-hardhat-mainnet-fork-562m</link>
      <guid>https://dev.to/george_k/smart-contracts-integration-testing-with-hardhat-mainnet-fork-562m</guid>
      <description>&lt;p&gt;In the Ethereum blockchain, the data and code of smart contracts are stored on-chain. Smart contracts can interact with each other in a permissionless manner, unlike Web 2.0 APIs that usually require authorization or are just inaccessible from a public network. Thereby composability is achieved. New decentralized applications can be created based on other applications and can be integrated with them.&lt;/p&gt;

&lt;p&gt;When creating such an application, it is important to be able to test integration with other applications, the interaction of smart contracts. For example, let's say you want to write a Swap Aggregator service that routes specific “swap” to one of the exchanges: Sushiswap, Uniswap, Curve, etc. The contract may look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SwapAggregator.sol

contract SwapAggregator {
  public uint256 SUSHISWAP = 0;
  public uint256 sushiswapRouter = 0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f;

  // other variables…

  function swap(uint256 dexId, address tokenIn, address tokenOut, uint256 amountIn) external {
    if (dexId == SUSHISWAP) {
      // here goes some interaction with Sushiswap router
      ISushiswapRouter(sushiswapRouter).swap(tokenIn, tokenOut, amountIn, msg.sender);
    } // else if ...
  }

  // other methods…
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need to make sure that your smart contract interacts correctly with the smart contracts of other exchanges. How can you do that?&lt;/p&gt;

&lt;h4&gt;
  
  
  Smart contract mocks
&lt;/h4&gt;

&lt;p&gt;First, hardhat provides convenient contract testing tools. You can write simplified versions of exchange contracts that have methods you need. For example, you can create a SushiswapRouter smart contract that has a &lt;code&gt;swap&lt;/code&gt; method with the desired functionality (and its interface matches the SushiswapRouter smart contract interface on the mainnet). Let’s have a look:&lt;br&gt;
&lt;/p&gt;

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

it("Should swap through Sushiswap", async () =&amp;gt; {
  const SushiswapRouter = await ethers.getContractFactory("SushiswapRouter");
  const sushiRouter = await SushiswapRouter.deploy();

  const SwapAggregator = await ethers.getContractFactory("SwapAggregator");
  const swapAggregator = await SwapAggregator.deploy(sushiRouter.address);

  const tx = await swapAggregator.swap(sushiswapId, USDC, 1000000)
  // validate tx receipt
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach has some disadvantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can implement functionality of a smart contract incorrectly, the test will pass locally, but your smart contract won’t work on the mainnet.&lt;/li&gt;
&lt;li&gt;It is difficult as you need to spend time implementing a test smart contract. And the more complex the integration, the more difficult it is to do.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Testing in testnet
&lt;/h4&gt;

&lt;p&gt;The second option is to deploy your contract on testnet and properly test the integration there. This is a good option and should be done in most cases. But sometimes it’s impossible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not all projects are deployed to testnet, thus, the smart contracts you need may simply not be available.&lt;/li&gt;
&lt;li&gt;There may not be all the necessary data (for example, any specific tokens that you want to support the exchange of)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Forking mainnet
&lt;/h4&gt;

&lt;p&gt;The third option is to check the integration on the local blockchain with state from the mainnet. Hardhat can fork mainnet.&lt;/p&gt;

&lt;p&gt;From &lt;a href="https://hardhat.org/hardhat-network/docs/guides/forking-other-networks"&gt;documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can start an instance of Hardhat Network that forks mainnet. This means that it will simulate having the same state as mainnet, but it will work as a local development network. That way you can interact with deployed protocols and test complex interactions locally&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To launch local node with state forked from the mainnet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat node --fork https://rpc.flashbots.net/ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can run tests&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat --network localhost test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;And you can interact with contracts from mainnet&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;// test:

it("Swap should work", async () =&amp;gt; {
  // Sushiswap router address in mainnet
  const sushiswapRouterAddress = "0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f"

  const SwapAggregator = await ethers.getContractFactory("SwapAggregator");
  const swapAggregator = await SwapAggregator.deploy(sushiswapRouterAddress);

  const tx = await swapAggregator.swap(sushiswapId, USDC, 1000000)
  // validate tx receipt
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, the fork will use the most recent mainnet block, so the tests will be run with different states. This is usually undesirable and hardhat allows you to create a fork from a specific block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat node --fork https://eth-mainnet.alchemyapi.io/v2/&amp;lt;key&amp;gt; --fork-block-number 14390000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It requires an archive node, for example, Alchemy. Just don't forget to replace  with your own key.&lt;/p&gt;

&lt;h4&gt;
  
  
  Funds for testing
&lt;/h4&gt;

&lt;p&gt;You may need funds to test some features of the smart contract (obviously, you need to have some tokens to exchange them). To get ETH, you can use &lt;code&gt;hardhat_setBalance&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await network.provider.send("hardhat_setBalance", [
  "0x0d2026b3EE6eC71FC6746ADb6311F6d3Ba1C000B",
  ethers.utils.parseUnits(1),
]);
// now account 0x0d2026b3EE6eC71FC6746ADb6311F6d3Ba1C000B has 1 ETH after this
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get some token, for example, USDC, you can exchange ETH for it using any exchange (in our example, we could use SwapAggregator for this).&lt;/p&gt;

&lt;h4&gt;
  
  
  Access to contracts
&lt;/h4&gt;

&lt;p&gt;In some cases, it may be necessary to change the configuration of other smart contracts, and for this, you need to have access to an account with such authority. &lt;code&gt;hardhat_impersonateAccount&lt;/code&gt; will help here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await hre.network.provider.request({
  method: "hardhat_impersonateAccount",
  params: ["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"],
});
//  after that, all transactions will be sent on behalf of 0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Other useful features
&lt;/h4&gt;

&lt;p&gt;For more complex cases, hardhat allows you to rewrite data in the storage of a smart contract or change the code of the entire contract. List of utility methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hardhat_impersonateAccount&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hardhat_stopImpersonatingAccount&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hardhat_setNonce&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hardhat_setBalance&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hardhat_setCode&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hardhat_setStorageAt&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can learn more about them in &lt;a href="https://hardhat.org/hardhat-network/docs/guides/forking-other-networks"&gt;the hardhat documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To sum up, using mainnet forking, you can test complex interactions with other apps. And deploy the contract being sure that everything will work on the mainnet.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>javascript</category>
      <category>hardhat</category>
      <category>ethereum</category>
    </item>
  </channel>
</rss>
