<?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: Akim B. (mousticke.eth)</title>
    <description>The latest articles on DEV Community by Akim B. (mousticke.eth) (@mousticke).</description>
    <link>https://dev.to/mousticke</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%2F216540%2F1b43a583-607c-4376-9bc6-31a5056807e6.jpeg</url>
      <title>DEV Community: Akim B. (mousticke.eth)</title>
      <link>https://dev.to/mousticke</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mousticke"/>
    <language>en</language>
    <item>
      <title>Ethereum UX: Account Abstraction (AA)</title>
      <dc:creator>Akim B. (mousticke.eth)</dc:creator>
      <pubDate>Wed, 07 Jan 2026 11:59:08 +0000</pubDate>
      <link>https://dev.to/mousticke/ethereum-ux-account-abstraction-aa-399a</link>
      <guid>https://dev.to/mousticke/ethereum-ux-account-abstraction-aa-399a</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you have been in the Web3 community for a while, you might have heard about Account Abstraction, or if you are just a Web2 user, it might have been difficult to step into a blockchain transaction with Ethereum since there are some concepts like gas fees, stipends, signatures, and so on. For all of us, Ethereum has brought an amazing EIP (4773) which improves significantly the UX for interacting with the protocol.&lt;/p&gt;

&lt;p&gt;Account abstraction makes Ethereum more user-friendly, secure, and ready for mass adoption by institutional and regular users. I have been playing around for a while, and I’d like to share with you what Account abstraction is, my insights, and what I’ve learned so far. Whether you're a developer, investor, or just crypto-curious, understanding AA could reshape how you think about wallets and transactions.&lt;/p&gt;

&lt;p&gt;Let's start with the basics...&lt;/p&gt;

&lt;p&gt;If you want to see a minimal implementation, please check a sample minimal account abstraction in my github repo: &lt;a href="https://github.com/Mousticke/eth-erc4337-minimal-account-abstraction/blob/main/src/ethereum/MinimalAccount.sol" rel="noopener noreferrer"&gt;https://github.com/Mousticke/eth-erc4337-minimal-account-abstraction/blob/main/src/ethereum/MinimalAccount.sol&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Account Abstraction?
&lt;/h2&gt;

&lt;p&gt;In the Ethereum blockchain, there are two main types of accounts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Externally Owned Accounts (EOAs): These are your standard wallets, controlled solely by a private key. They can't contain any EVM (Ethereum Virtual Machine) code. They're simple and straightforward.&lt;/li&gt;
&lt;li&gt;Smart Contract Accounts: These hold executable code and are governed by that code's logic, not a single private key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem with EOAs? They're a bit hard to hand on by the common user and risky:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once you sign a transaction or lose your key, there's no recovery mechanism. One mistake, and your funds could be gone forever.&lt;/li&gt;
&lt;li&gt;They rely on ECDSA signatures, which aren't quantum-resistant.&lt;/li&gt;
&lt;li&gt;This setup isn't ideal for mainstream users who expect seamless, forgiving experiences like in Web2 apps without caring too much about signature, gas fee, secret keys. Plus, there is no sponsors to pay fees on our behalf.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So what is the alternative ? Here comes the Account Abstraction.&lt;/p&gt;

&lt;p&gt;It blurs the lines between EOAs and contracts, turning every account into a programmable smart contract. You define custom logic, validation rules, and flows, making accounts smarter, safer, and more flexible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Do We Need AA?
&lt;/h2&gt;

&lt;p&gt;Blockchain's biggest barrier to adoption is poor UX. AA solves this by enabling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customizable security: Add multi-factor auth, social recovery, or spending limits without relying on a single key.&lt;/li&gt;
&lt;li&gt;Quantum-proofing: Swap out ECDSA for more secure schemes.&lt;/li&gt;
&lt;li&gt;Seamless integration: Make crypto feel like everyday apps, reducing friction for non-technical users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, AA paves the way for billions of users by making blockchain as intuitive as logging into your bank account.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Components of AA (ERC-4337 Standard)
&lt;/h2&gt;

&lt;p&gt;ERC-4337 enables account abstraction without requiring changes to Ethereum's consensus layer. It introduces a parallel system using an alternative mempool, allowing smart contract wallets (programmable accounts) to replace or augment traditional Externally Owned Accounts (EOAs).&lt;/p&gt;

&lt;p&gt;Here's the core system&lt;/p&gt;

&lt;h3&gt;
  
  
  1. UserOperations (UserOps)
&lt;/h3&gt;

&lt;p&gt;These are ABI-encoded structures that represent user intents (send ETH or swap tokens). It's not a real Ethereum transaction but a structured data packet sent to a dedicated mempool. Which means they can't access block-level info (like timestamps) to prevent manipulation, and they only interact with the sender's data. Ops flow through a decentralized peer-to-peer alt-mempool, avoiding centralized bottlenecks.&lt;/p&gt;

&lt;p&gt;Main fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sender&lt;/code&gt; : The smart contract account address.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nonce&lt;/code&gt; : Prevents replays.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;initCode&lt;/code&gt; : (Optional) Code to deploy the account if it doesn't exist (using a Factory).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;callData&lt;/code&gt; : The action to execute (transfer tokens).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;callGasLimit&lt;/code&gt;, &lt;code&gt;verificationGasLimit&lt;/code&gt;, &lt;code&gt;preVerificationGas&lt;/code&gt; : Gas estimates.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;maxFeePerGas&lt;/code&gt;, &lt;code&gt;maxPriorityFeePerGas&lt;/code&gt; : Like regular txs. Fees you put on MM for example.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;paymasterAndData&lt;/code&gt; : (Optional) Paymaster info for sponsorship.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;signature&lt;/code&gt; : Custom signature (validated by the account).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Users/wallets create and sign &lt;code&gt;UserOps&lt;/code&gt;, then broadcast them to the &lt;code&gt;alt-mempool&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Alt-mempool
&lt;/h3&gt;

&lt;p&gt;A peer-to-peer network separate from the main Ethereum mempool. &lt;code&gt;UserOps&lt;/code&gt; propagate here, keeping the system decentralized (no central relayer required).&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Bundler
&lt;/h3&gt;

&lt;p&gt;Think of this as a specialized node. It monitors the &lt;code&gt;UserOp&lt;/code&gt; mempool (alt-mempool), bundles multiple ops together, simulates them to calculate gas fees, and submits them to the &lt;code&gt;EntryPoint&lt;/code&gt; via &lt;code&gt;handleOps()&lt;/code&gt;. Fees can be paid by the account itself or a &lt;code&gt;Paymaster&lt;/code&gt;. &lt;code&gt;Bundlers&lt;/code&gt; get reimbursed for gas (plus tips) from accounts or paymasters.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. EntryPoint
&lt;/h3&gt;

&lt;p&gt;A global smart contract deployed one per chain that handles everything. The entrypoint receives bundled &lt;code&gt;UserOps&lt;/code&gt; from bundlers and runs in two phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verification Phase : Checks signatures, nonces, and custom rules by calling account. &lt;code&gt;validateUserOp()&lt;/code&gt; (and paymaster if used) to check signature, nonce, and rules.&lt;/li&gt;
&lt;li&gt;Execution Phase: Actually performs the ops on-chain which can handles staking, deposits, withdraw, and post ops logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Smart Account (user’s wallet)
&lt;/h3&gt;

&lt;p&gt;The user's programmable account. Must implement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;validateUserOp()&lt;/code&gt; : Custom logic (ECDSA, multisig, session keys).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;execute()&lt;/code&gt; : Perform the action.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Paymaster
&lt;/h3&gt;

&lt;p&gt;A contract that sponsors transactions. It can cover gas fees on behalf of users, enabling gasless experiences.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Aggregator
&lt;/h3&gt;

&lt;p&gt;For efficiency, accounts can batch signatures using an aggregator, compressing multiple sigs into one to save on gas and data.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Factory
&lt;/h3&gt;

&lt;p&gt;Deploys the account via &lt;code&gt;CREATE2&lt;/code&gt; if &lt;code&gt;initCode&lt;/code&gt; is provided.&lt;/p&gt;




&lt;h2&gt;
  
  
  Transaction flow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;User creates/signs a &lt;code&gt;UserOp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Broadcast to &lt;code&gt;alt-mempool&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Bundler&lt;/code&gt; collects, simulates, bundles, and calls &lt;code&gt;EntryPoint.handleOps(bundle)&lt;/code&gt; .&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EntryPoint&lt;/code&gt; verifies ( account + paymaster ) → executes → refunds/reimburses.&lt;/li&gt;
&lt;li&gt;On-chain as one tx from the bundler.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;p&gt;AA isn't theoretical. It's powering innovative apps today. Here are a couple of examples&lt;/p&gt;

&lt;h3&gt;
  
  
  Pay Gas Fees in Any ERC-20 Token
&lt;/h3&gt;

&lt;p&gt;No more scrambling for ETH! Imagine a merchant checkout: A user places a $100 order in USDC. The Paymaster covers the gas fee (say, 1 USDC from the user), converts it to ETH, and pays the network. The merchant receives the full 100 USDC. This abstracts away crypto's "gas hassle," making it feel like a regular online purchase.&lt;/p&gt;

&lt;p&gt;Connect your wallet using Google, Apple ID, or even biometrics. No seed phrases or manual gas settings required. For beginners, this eliminates the "What’s a private key?" confusion, turning crypto into a plug-and-play experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Signing with Google or Apple ID (Passkeys)
&lt;/h2&gt;

&lt;p&gt;But I have mentioned earlier that you can even use your google account or apple id as a wallet by signing transaction directly by your fingerprint or face ID. That’s one of the most exciting feature turning a Web3 hassle into a Web2-like logins for blockchain wallets. You can now "connect" or sign transactions using your Google account, Apple ID, or device biometrics (Face ID/Touch ID). no seed phrases, no private keys to manage, and no confusing gas settings. This is powered by passkeys (based on the WebAuthn standard), turning your smart contract wallet into something that feels like logging into any modern app.&lt;/p&gt;

&lt;p&gt;Instead of ECDSA signatures from a private key, the wallet can validate any signature scheme, including passkeys.&lt;/p&gt;

&lt;p&gt;Passkeys are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cryptographic credentials created and stored securely on your device (in Apple's Secure Enclave or Google's Password Manager).&lt;/li&gt;
&lt;li&gt;Unlocked via biometrics (Face ID, fingerprint) or PIN.&lt;/li&gt;
&lt;li&gt;Synced securely across devices via iCloud or Google.&lt;/li&gt;
&lt;li&gt;Phishing-resistant and passwordless.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you sign in with Google or Apple ID&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's actually creating/registering a passkey tied to your account.&lt;/li&gt;
&lt;li&gt;The private key never leaves your device. It's generated and stored in hardware-secured areas.&lt;/li&gt;
&lt;li&gt;The public key is registered on-chain with your smart wallet.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Account abstraction flow with Apple ID / Google
&lt;/h3&gt;

&lt;p&gt;In your DApp, choose to sign in with Google or Apple. Your device uses &lt;code&gt;WebAuthn&lt;/code&gt; API to generate a passkey (private/public key pair). Then the smart contract account is deployed (via a Factory in &lt;code&gt;ERC-4337&lt;/code&gt;). The public key is stored in the account as the owner.&lt;/p&gt;

&lt;p&gt;Then it’s time to create a transaction. You may want to send tokens or swap on the DApp. The wallet creates a &lt;code&gt;UserOperation&lt;/code&gt; (your intent). Instead of signing with a private key, it prompts your device by requiring your biometric ID. &lt;code&gt;WebAuthn&lt;/code&gt; signs the &lt;code&gt;UserOp&lt;/code&gt; hash using the passkey (on-device, secure). The signature (&lt;code&gt;P256 curve&lt;/code&gt;) is sent with the &lt;code&gt;UserOp&lt;/code&gt; to a &lt;code&gt;Bundler&lt;/code&gt;. (There is an extra step because &lt;code&gt;P256&lt;/code&gt; is different from the &lt;code&gt;secp256k1&lt;/code&gt;. We will talk later about it).&lt;/p&gt;

&lt;p&gt;Ultimately, the &lt;code&gt;EntryPoint&lt;/code&gt; contract calls your smart wallet's &lt;code&gt;validateUserOp()&lt;/code&gt;, verifies the signature and process to the operations like we described above.&lt;/p&gt;

&lt;p&gt;Hold on mate ! The private key from a Google or Apple passkey never leaves the device (it's stored in the secure enclave/hardware module and can't be exported). So, Solidity code on-chain can't access or use it directly to sign anything ? And my friend your right !&lt;/p&gt;

&lt;p&gt;Instead, the device uses &lt;code&gt;WebAuthn&lt;/code&gt; to sign the message/hash with the passkey private key on the client side (off-chain). Then, the smart contract wallet verifies the signature using the corresponding public key which is stored on-chain. This is possible because Account Abstraction (&lt;code&gt;ERC-4337&lt;/code&gt;) allows custom signature validation in the &lt;code&gt;validateUserOp&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Passkeys use the &lt;code&gt;secp256r1&lt;/code&gt; elliptic curve (also called &lt;code&gt;P-256&lt;/code&gt;), not Ethereum's native &lt;code&gt;secp256k1&lt;/code&gt;. But Ethereum has a built-in precompile for &lt;code&gt;secp256k1&lt;/code&gt; (via &lt;code&gt;ecrecover&lt;/code&gt;), but not for &lt;code&gt;P-256&lt;/code&gt;. So the verification requires a custom Solidity code to implement &lt;code&gt;P-256&lt;/code&gt; signature checking. This is expensive in gas. Check this out here : &lt;a href="https://github.com/daimo-eth/p256-verifier/blob/master/src/P256Verifier.sol" rel="noopener noreferrer"&gt;https://github.com/daimo-eth/p256-verifier/blob/master/src/P256Verifier.sol&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Benefits are huge
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;No Seed Phrases: Ever. Recovery via iCloud/Google sync.&lt;/li&gt;
&lt;li&gt;Gasless and Seamless: Paymasters can sponsor fees. You pay in USDC or nothing at all.&lt;/li&gt;
&lt;li&gt;Secure: Keys in hardware, biometrics required, phishing-resistant.&lt;/li&gt;
&lt;li&gt;Cross-Device: Lose your phone? Recover via another device signed into the same Google/Apple account.&lt;/li&gt;
&lt;li&gt;Mass Adoption Ready: Feels exactly like logging into Gmail&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;AA is already live on networks like Ethereum (via &lt;code&gt;ERC-4337&lt;/code&gt;) and is being adopted. It's a cornerstone for scaling Web3 to the masses.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>cryptocurrency</category>
    </item>
    <item>
      <title>Understand the ZK Rollups</title>
      <dc:creator>Akim B. (mousticke.eth)</dc:creator>
      <pubDate>Sat, 28 Oct 2023 21:56:52 +0000</pubDate>
      <link>https://dev.to/mousticke/understand-the-zk-rollups-3aoj</link>
      <guid>https://dev.to/mousticke/understand-the-zk-rollups-3aoj</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;Imagine you have a Christmas gift to send to your family for the next Christmas and you have 4 gifts to send. One option is to send 4 different parcels to your family location. But it will be expensive and/or maybe some delays between each parcels. What if you send all the gifts at once in a single parcel containing each parcel? It will be less expensive and you save time and effort. &lt;br&gt;
If you understand this small abstract, you'll understand what ZK rollups are and how they scale Ethereum network. Let's dive into them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Rollup.
&lt;/h2&gt;

&lt;p&gt;If you refer to the Ethereum website, the definition is a bit hard to understand. I'll try to make it easier for you to explain as I dedicate this article to everybody with or without deep knowledge about the blockchain.&lt;br&gt;
On the Ethereum blockchain, there are two things that can be posted on the blockchain. &lt;strong&gt;Transactions&lt;/strong&gt; or &lt;strong&gt;Data&lt;/strong&gt;.&lt;br&gt;
A transaction is just the action to send ETH between two addresses.&lt;br&gt;
A data can be stored on the Ethereum blockchain which makes it different from Bitcoin. A data can be anything. A simple text or a compiled code which are smart-contracts.&lt;br&gt;
A rollup is a solution that performs a bunch or a bundle of transactions execution outside the mainnet and post the final transactions data to the mainnet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blocks in Ethereum
&lt;/h2&gt;

&lt;p&gt;But first, you need to know that the block size isn't dynamic and unlimited in space. A block has a target of 15 million gas but depending on the networks demand, the block can increase to 30 million of gas. The total amount of gas expended by all transactions in the block must be less than the block gas limit. This is important because it ensures that blocks can’t be arbitrarily large. If blocks could be arbitrarily large, then less performant full nodes would gradually stop being able to keep up with the network due to space and speed requirements. A block is proposed every 12 seconds.&lt;br&gt;
Based on this statement, let's say that there are 100,000 transactions and every block can process 100 transactions. The priority of the validated blocks go for people who add a tip in the gas fee for the validator. Others transactions have to wait. Depending on the demand of the networks, a transaction can be delayed and slow. A fee can be more and more expensive so each transactions have to be more and more important to be included in priority.&lt;br&gt;
As mentioned earlier, the Ethereum blockchain can handle data. We can perform some transactions in this data. &lt;br&gt;
So what if one data can perform 10 transactions and we can process only 100 transactions or data in one block to the blockchain? We have scaled the Ethereum blockchain to 1000 transactions per block. This is what rollups are about.&lt;/p&gt;

&lt;h2&gt;
  
  
  A single transaction
&lt;/h2&gt;

&lt;p&gt;A simple Ethereum transaction (to send ETH) takes around 110 bytes. An ETH transfer on a rollup, however, takes only 12 bytes&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Ethereum&lt;/th&gt;
&lt;th&gt;Rollup&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nonce&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gasprice&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gas&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Value&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signature&lt;/td&gt;
&lt;td&gt;2 + 33 +33 (68)&lt;/td&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;From&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total&lt;/td&gt;
&lt;td&gt;112&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  How does a rollup work?
&lt;/h2&gt;

&lt;p&gt;There is a smart contract on-chain which maintains the Merkle root of the state of the rollup. Anyone can publish a batch of transactions in a highly compressed form together with the previous state root and the new state root. The contract checks that the previous state root in the batch matches its current state root. If it does, it switches the state root to the new state root. &lt;br&gt;
How to do know that the post-state roots in the batches are correct? The answer to this question is the main key of the solution proposed by the two families of rollup.&lt;/p&gt;

&lt;h2&gt;
  
  
  ZKsnarks Rollup
&lt;/h2&gt;

&lt;p&gt;If you break down the acronym Zero Knowledge Succinct Non-Interactive Argument of Knowledge you have:&lt;br&gt;
&lt;strong&gt;Zero Knowledge&lt;/strong&gt;: No need to see the transactions data&lt;br&gt;
&lt;strong&gt;Succinct&lt;/strong&gt;: Short&lt;br&gt;
&lt;strong&gt;Non-Interactive&lt;/strong&gt;: No need to deal with the people who verify the work&lt;br&gt;
&lt;strong&gt;Argument of Knowledge&lt;/strong&gt;: Proof they provided that these transactions are good.&lt;br&gt;
ZKSnark or Zero Knowledge Succinct Non-Interactive Argument of Knowledge runs a computation off chain and submit a validity proof on chain.&lt;br&gt;
A validity proof is the result of a computation and mathematically verified to be not fraudulent. So this rollup needs more computation and time to be submitted to the network. (If you want to know more about Zero Knowledge, you can find the paper on the internet. It a concept invented in 1985 by Silvio Micali).&lt;br&gt;
Then, once this validity proof is created, it will be submitted to the blockchain and approved to the Layer 1. This computation off chain means that the Ethereum blockchain has offloaded some work to the ZKSnark checker which is what a Layer 2 solution does. Unlikely to the Optimistic rollup, once the validity proof is submitted, the funds are directly available to the user. However, it's more difficult to create an EVM compatible ZK rollup. You can check ZK-Sync for this part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimistic Rollup
&lt;/h2&gt;

&lt;p&gt;This rollup is used by Arbitrum and Optimism because it's easier to implement. These L2 use a single centralised node called a Sequencer that submits the transactions. &lt;br&gt;
It assumes that the transactions are good and valid by default. Instead of submitting a validity proof, the optimistic rollups submit a fraud proof but only if the transactions are challenged by the networks.&lt;br&gt;
So this rollup assumes that everybody tell the truth. They dont do some computation like ZKSnarks do. However, what they do post, is fact check-able by the network. Because transactions involves money, there will be always some people checking the transactions. So if the network attests that a transaction is fraudulent, the transaction is reverted and the block validator is slashed. That's why in Optimitic rollup, you have a challenge period where the nodes can use a verifier (contract) to check the transactions. The challenge period can last for one week and during this time, the user cannot withdraw the funds. The other drawback of this rollup is the sequencer. It's centralised and prone to censorship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;In short, here a table comparing the two solutions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rollup property/Rollup solution&lt;/th&gt;
&lt;th&gt;Optimistic&lt;/th&gt;
&lt;th&gt;ZK Rollup&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fixed gas cost per batch&lt;/td&gt;
&lt;td&gt;40,000 (a lightweight transaction that mainly just changes the value of the state root)&lt;/td&gt;
&lt;td&gt;~500,000 (verification of a ZK-SNARK is quite computationally intensive)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Withdrawal period&lt;/td&gt;
&lt;td&gt;1 week (withdrawals need to be delayed to give time for someone to publish a fraud proof and cancel the withdrawal if it is fraudulent)&lt;/td&gt;
&lt;td&gt;Very fast (just wait for the next batch)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity of technology&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High (ZKSnarks are mathematically complex technology)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>ethereum</category>
      <category>blockchain</category>
      <category>layer</category>
    </item>
    <item>
      <title>Setting up an Ethereum Node (Execution Client)</title>
      <dc:creator>Akim B. (mousticke.eth)</dc:creator>
      <pubDate>Sat, 10 Sep 2022 17:55:33 +0000</pubDate>
      <link>https://dev.to/mousticke/setup-an-ethereum-node-execution-client-2k74</link>
      <guid>https://dev.to/mousticke/setup-an-ethereum-node-execution-client-2k74</guid>
      <description>&lt;h2&gt;
  
  
  Caveat
&lt;/h2&gt;

&lt;p&gt;It's still possible to run the execution client (layer 1) alone but after the Merge in the upcoming days, we need to run the execution client and consensus client to be able to access to the Ethereum network. In this article, I will cover the &lt;code&gt;execution layer&lt;/code&gt; &lt;strong&gt;only&lt;/strong&gt;. &lt;br&gt;
The execution client listens to new transactions and executes them in the EVM (state machine) and holds the database of Ethereum network.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;See the overview of execution client in &lt;a href="https://ethernodes.org/" rel="noopener noreferrer"&gt;Etherenodes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;See the execution layer specification in &lt;a href="https://github.com/ethereum/execution-specs/" rel="noopener noreferrer"&gt;Ethereum Repo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;This article covers the node running from the source code or from the package in Ubuntu&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;u&gt;Table Of Contents&lt;/u&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Abstract&lt;/li&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Node Types&lt;/li&gt;
&lt;li&gt;Why should I run a node&lt;/li&gt;
&lt;li&gt;Installation&lt;/li&gt;
&lt;li&gt;Create the chaindata folder&lt;/li&gt;
&lt;li&gt;Run the node&lt;/li&gt;
&lt;li&gt;Interacting with Geth&lt;/li&gt;
&lt;li&gt;Run the node (dev mode / contributor)&lt;/li&gt;
&lt;li&gt;Next Step&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;u&gt;Abstract&lt;/u&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Little abstract before jumping in our journey with the Ethereum node.&lt;br&gt;
Ethereum is a distributed decentralised network of computers. Each computer in this network is running a software that contains the history of the blockchain, the ability to validate/mine blocks and transactions.&lt;br&gt;
In order to be a node in the Ethereum network, a client needs to download this software that implements the specification of the yellow paper to be able to communicate within the network.&lt;br&gt;
In this article, the client I'll be choosing is Geth. It's the most popular client and backed by the Ethereum Community.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;u&gt;Prerequisites &lt;/u&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You can run a node on any computers but it's worth to consider running your Ethereum node in a dedicated hardware to minimise the performance issues.&lt;br&gt;
Make sure to have a stable internet connection. Even though you can go offline, your node goes inactive until you come back and download the latest changes from other nodes automatically. &lt;br&gt;
You can buy hardware from a vendor and have a plug and play node or you can build your own. The last option is cheaper and funnier.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;Hardware&lt;/u&gt;
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;u&gt;Minimum&lt;/u&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;8GB RAM (16GB for a validator);&lt;/li&gt;
&lt;li&gt;2TB SSD for write speeds (12TB for Archive node);&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;Recommended&lt;/u&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU with a benchmark score of 6667+&lt;/li&gt;
&lt;li&gt;16GB RAM (32GB for a validator);&lt;/li&gt;
&lt;li&gt;Unlimited High speed internet bandwidth;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  &lt;u&gt;Node types&lt;/u&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In order to run your node, you need to be aware of the node types. Each node type consumes data differently. There are 3 node type:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Light Node&lt;/li&gt;
&lt;li&gt;Full Node&lt;/li&gt;
&lt;li&gt;Archive Node&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;Light Node&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;Instead of downloading the entire blockchain, you can download a shallow copy of the data containing only the block headers. A light node relies on a full node to get more data. A light node can also verify the data and participate to the network. The drawback is that you cannot participate in a consensus, you cannot be a miner nor a validator.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;Full Node&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;The full node stores all block data not since the &lt;code&gt;Genesis&lt;/code&gt;. This is periodically pruned and get only the most recent 128 blocks. A full node can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Participate in a consensus;&lt;/li&gt;
&lt;li&gt;Validate blocks; &lt;/li&gt;
&lt;li&gt;Verify the states;&lt;/li&gt;
&lt;li&gt;Serve the network and provide data on request;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The drawback is that you cannot query data at block #1,000,000 because you don't have the entire history. Only the 128 last blocks. &lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;Archive Node&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;The archive node stores the historical states since the &lt;code&gt;Genesis&lt;/code&gt;. Basically, if you want the query data since the first block, you can with the archive node.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;u&gt;Why should I run a node?&lt;/u&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If you really believe in Ethereum, and decentralised crypto currency, you should consider running a node.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;For me&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;You can use Ethereum privately and verify the data yourself. "Don't trust, verify" is a popular Blockchain mantra.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't rely on another node&lt;/li&gt;
&lt;li&gt;Use an Ethereum wallet within the node and use DApps more securely and privately without leaking your address and balance to another node.&lt;/li&gt;
&lt;li&gt;Build your custom RPC endpoint&lt;/li&gt;
&lt;li&gt;Stake your ETH and earn rewards (be a validator with 32ETH)&lt;/li&gt;
&lt;li&gt;Allow wallets provider like &lt;code&gt;Metamask&lt;/code&gt; to use your node&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;For the Network&lt;/u&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Enforce the consensus rules&lt;/li&gt;
&lt;li&gt;Social recovery in case of massive attack&lt;/li&gt;
&lt;li&gt;More diverse and robust network and provide a censorship-resistant ecosystem&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;u&gt;Installation&lt;/u&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Golang
&lt;/h4&gt;

&lt;p&gt;In order to download the source code, you need to install &lt;a href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git" rel="noopener noreferrer"&gt;git command&lt;/a&gt;.&lt;br&gt;
&lt;code&gt;geth&lt;/code&gt; is a software coded in golang. You need to install &lt;a href="https://go.dev/dl/" rel="noopener noreferrer"&gt;Go&lt;/a&gt; before. &lt;/p&gt;

&lt;p&gt;If you are on Windows and have &lt;code&gt;Chocolatey&lt;/code&gt; installed, you can run (Admin mode) these commands:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

choco &lt;span class="nb"&gt;install &lt;/span&gt;git
choco &lt;span class="nb"&gt;install &lt;/span&gt;golang
choco &lt;span class="nb"&gt;install &lt;/span&gt;mingw


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

&lt;/div&gt;

&lt;p&gt;(If you run these commands, you'll need to close your terminal and open up a new one)&lt;/p&gt;

&lt;p&gt;Then you can follow one of these steps in order to have Geth installed: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download Source code (Windows) or&lt;/li&gt;
&lt;li&gt;Download Source Code (Linux) or&lt;/li&gt;
&lt;li&gt;Download the Package (Ubuntu)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;Download Source code (Windows)&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;In order to download the source code, you can copy and paste these commands: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;mkdir &lt;/span&gt;src&lt;span class="se"&gt;\g&lt;/span&gt;ithub.com&lt;span class="se"&gt;\e&lt;/span&gt;thereum
git clone git@github.com:ethereum/go-ethereum.git src&lt;span class="se"&gt;\g&lt;/span&gt;ithub.com&lt;span class="se"&gt;\e&lt;/span&gt;thereum&lt;span class="se"&gt;\g&lt;/span&gt;o-ethereum
&lt;span class="nb"&gt;mkdir &lt;/span&gt;src&lt;span class="se"&gt;\g&lt;/span&gt;ithub.com&lt;span class="se"&gt;\e&lt;/span&gt;thereum&lt;span class="se"&gt;\g&lt;/span&gt;o-ethereum


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

&lt;/div&gt;

&lt;p&gt;You should have this output:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd07pli4qx04uo50qzd2a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd07pli4qx04uo50qzd2a.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can now build the project from the binaries&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

go get &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; golang.org/x/net/context
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; ./cmd/...


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

&lt;/div&gt;

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

&lt;h4&gt;
  
  
  &lt;u&gt;Download Source Code (Linux)&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;If you have Linux (or MacOS), it's slightly different. You can just run this command: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

go get &lt;span class="nt"&gt;-d&lt;/span&gt; github.com/ethereum/go-ethereum


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

&lt;/div&gt;

&lt;p&gt;If you have an existing Geth client, you can update with this command&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

go get &lt;span class="nt"&gt;-u&lt;/span&gt; github.com/ethereum/go-ethereum


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

&lt;/div&gt;
&lt;h4&gt;
  
  
  &lt;u&gt;Download the Package (Ubuntu)&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;You need to add the launchpad repository&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;add-apt-repository &lt;span class="nt"&gt;-y&lt;/span&gt; ppa:ethereum/ethereum


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

&lt;/div&gt;

&lt;p&gt;Then you can download the stable version of go-ethereum&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;ethereum


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

&lt;/div&gt;

&lt;p&gt;If you have an existing geth installation, you can get the latest version with the following commands:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;ethereum
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get upgrade geth


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

&lt;/div&gt;




&lt;h3&gt;
  
  
  &lt;u&gt;Create the chaindata folder&lt;/u&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In order to store the chain data, you need to create a folder somewhere in your system. I usually create the chain data at the same level of the binary (in my case)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ./chain/data


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

&lt;/div&gt;

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

&lt;h3&gt;
  
  
  &lt;u&gt;Run the node&lt;/u&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Now you are ready for running the node.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

geth console &lt;span class="nt"&gt;--syncmode&lt;/span&gt; full &lt;span class="nt"&gt;--networkid&lt;/span&gt; 1 &lt;span class="nt"&gt;--gcmode&lt;/span&gt; full &lt;span class="nt"&gt;--datadir&lt;/span&gt; ..&lt;span class="se"&gt;\c&lt;/span&gt;hain&lt;span class="se"&gt;\d&lt;/span&gt;ata&lt;span class="se"&gt;\&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;What I'm doing here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;geth: command line interface for the client&lt;/li&gt;
&lt;li&gt;console: start geth environment&lt;/li&gt;
&lt;li&gt;syncmode full: blockchain sync mode to full (default to snap)&lt;/li&gt;
&lt;li&gt;networkid 1: run the mainnet (by default it runs the mainnet)&lt;/li&gt;
&lt;li&gt;gcmode full: Garbage collection (full or archive)&lt;/li&gt;
&lt;li&gt;datadir: chaindata folder path that I have created earlier on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can run a testnet node if you want to. You need to remove &lt;code&gt;--networkid 1&lt;/code&gt; and replace by &lt;code&gt;--ropsten&lt;/code&gt; or &lt;code&gt;--goerli&lt;/code&gt; or &lt;code&gt;kiln&lt;/code&gt; or &lt;code&gt;sepolia&lt;/code&gt; or &lt;code&gt;rinkeby&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;geth --help&lt;/code&gt; to see the full list of commands&lt;/p&gt;

&lt;p&gt;Once you have executed this command, you should have this output&lt;/p&gt;

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

&lt;p&gt;You will see that it will be searching for peers and download the blockchain data since the genesis (7 years 2 month and 5 days in my case)&lt;/p&gt;

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

&lt;p&gt;(It's running in foreground. As soon as you close the terminal or press Ctrl+C / Ctrl+D, it will shutdown the node). If you want to run a node in a foreground or using as a service in Ubuntu, there are a lot of documentation for you. This is not the purpose of this article.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;u&gt;Interacting with Geth&lt;/u&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You can interact with your node by attaching it to the datadir&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

geth attach &lt;span class="nt"&gt;--datadir&lt;/span&gt; ..&lt;span class="se"&gt;\c&lt;/span&gt;hain&lt;span class="se"&gt;\d&lt;/span&gt;ata&lt;span class="se"&gt;\&lt;/span&gt;


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

&lt;/div&gt;

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

&lt;p&gt;You can see what is the current block being downloaded and the highest block by executing this command in the interactive console&lt;br&gt;
&lt;code&gt;eth.syncing&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;You can also execute Javascript code. In this example, I execute this snippet to know every 10 seconds the number of blocks per seconds being downloaded, the percentage of data downloaded and the remaining time&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;var&lt;/span&gt; &lt;span class="nx"&gt;lastPercentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;lastBlocksToGo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;timeInterval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;percentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;syncing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentBlock&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;syncing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;highestBlock&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;percentagePerTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;percentage&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;lastPercentage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;blocksToGo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;syncing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;highestBlock&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;syncing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentBlock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;bps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastBlocksToGo&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;blocksToGo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeInterval&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;etas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;percentagePerTime&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeInterval&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;etaM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;etas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;% ETA: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;etaM&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; minutes @ &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;bps&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bps&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

     &lt;span class="nx"&gt;lastPercentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;lastBlocksToGo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;blocksToGo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="nx"&gt;timeInterval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

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

&lt;p&gt;The number of block will be decreasing because over the year, there are more and more transaction in a block and you will be downloading more data in a full node in the last 128 blocks.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;u&gt;Run the node (dev mode / contributor)&lt;/u&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;The purpose of this article is not to help you running in dev mode. So I won't detail too much.&lt;/em&gt;&lt;br&gt;
If you want to contribute to the Ethereum client, you can run the command geth in dev mode without putting your assets at risk. There is a &lt;code&gt;--dev&lt;/code&gt; flag that run &lt;code&gt;geth&lt;/code&gt; in dev mode. In this way you have a node with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data directory with a testing genesis block&lt;/li&gt;
&lt;li&gt;Max peers to 0. That means that Geth won't search for peers (default to 50)&lt;/li&gt;
&lt;li&gt;The node won't be visible to other nodes&lt;/li&gt;
&lt;li&gt;Gas price is set at 0 wei&lt;/li&gt;
&lt;li&gt;PoA (Proof of Authority) in order to mine block on demand&lt;/li&gt;
&lt;li&gt;Generate Block on demand.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, you can run this command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

geth &lt;span class="nt"&gt;--dev&lt;/span&gt; &lt;span class="nt"&gt;--http&lt;/span&gt; &lt;span class="nt"&gt;--http&lt;/span&gt;.api eth,web3,personal,net &lt;span class="nt"&gt;--http&lt;/span&gt;.corsdomain &lt;span class="s2"&gt;"http://remix.ethereum.org"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;(See the full help from the command &lt;code&gt;geth --help&lt;/code&gt;)&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;u&gt;Next Steps&lt;/u&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The next step is to run the consensus layer in order to be able to participate in the network after the merge.&lt;br&gt;
After that, we will be covering the setup of a private node.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;u&gt;Conclusion &lt;/u&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Here you have just an overview on how to setup an Ethereum node. There are more to cover like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using Clef as ab account management for Geth that allows to sign transaction&lt;/li&gt;
&lt;li&gt;Create a specific user to setup the node and give privilege&lt;/li&gt;
&lt;li&gt;Port forwarding for your node&lt;/li&gt;
&lt;li&gt;Miner options from the command line (will be deprecated)&lt;/li&gt;
&lt;li&gt;Auto start on boot in Linux
And more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading and have fun in the decentralised world :)&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>etherereum</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Solidity : Gas Optimisation</title>
      <dc:creator>Akim B. (mousticke.eth)</dc:creator>
      <pubDate>Fri, 15 Jul 2022 18:09:46 +0000</pubDate>
      <link>https://dev.to/mousticke/solidity-gas-optimisation-5425</link>
      <guid>https://dev.to/mousticke/solidity-gas-optimisation-5425</guid>
      <description>&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;On Chain or Off Chain&lt;/li&gt;
&lt;li&gt;Solidity Optimiser&lt;/li&gt;
&lt;li&gt;EVM Slots&lt;/li&gt;
&lt;li&gt;Loop through an array&lt;/li&gt;
&lt;li&gt;Libraries&lt;/li&gt;
&lt;li&gt;Events&lt;/li&gt;
&lt;li&gt;Computed Values&lt;/li&gt;
&lt;li&gt;Constants&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Introduction &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;When writing smart contract in Solidity, you may not be really concerned about the gas consumption in Remix environment or in a testnet. You only realise how much cost every OPCODES when you deploy in the mainnet on Ethereum (or in L2 but it's quite cheap).&lt;br&gt;
Today, we will cover some optimisation we can do in Solidity. This list is not exhaustive and feel free to test every option you can.&lt;/p&gt;

&lt;p&gt;The very first rule we keep in mind is : Every state variable we update cost you some fees. For more information, you can see the following documentation : &lt;a href="https://ethereum.org/en/developers/docs/evm/opcodes/" rel="noopener noreferrer"&gt;Opcode&lt;/a&gt;. Many EIP try to optimise or adjust the gas cost of operations in the EVM. (EIP 2929, EIP 1559 for example)&lt;/p&gt;


&lt;h3&gt;
  
  
  On Chain or Off Chain Data &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;As mentioned above, writing state variable cost you some gas. That's why you should be aware that every user's call can cost a lot. You should be asking : "Do I really need to store this information on chain ?"&lt;br&gt;
Every data related to the "ecosystem" or that doesn't need to be censored should be inside your smart contract. When it comes to metadata, files you can handle them off chain.&lt;/p&gt;


&lt;h3&gt;
  
  
  Solidity Optimiser &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;It's a mode that enable to produce a more efficient bytecode by reducing, the code size or the gas needed for the deployment. Keep in mind that the optimiser is not turned on by default because it takes more time to compile the actual solidity code which is not efficient in development mode. Turn on the optimiser when you want to deploy your smart contract&lt;/p&gt;


&lt;h3&gt;
  
  
  EVM Slots &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You have probably seen or heard someone telling you to order your state variables by type ?&lt;br&gt;
This is not without any reason. The EVM stores the data of a smart contract into a memory slots of 256 bits. A uint256 will fill one slot. But a uint128 will fill 128 bits over 256. if the next state variable is a uint256 then, the variable will be stored in the next slot. The EVM will perform a computation to force the previous slots to fit the remaining space.&lt;br&gt;
Take this code :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uint128 variable_1
uint128 variable_2
uint256 variable_3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;variable_1&lt;/code&gt; will be stored in slot 0. Then &lt;code&gt;variable_2&lt;/code&gt; can fit inside the slot 0 because it has a remaining space of 128 bits.&lt;br&gt;
After that, the &lt;code&gt;variable_3&lt;/code&gt; will be stored in slot 1.&lt;/p&gt;

&lt;p&gt;In a not optimised version we can have this code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;address address_1
uint128 variable_1
uint256 variable_2
address address_2
uint128 variable_3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;address_1&lt;/code&gt; is 160 bits long (address is a 20 bytes type). It will be stored in slot 0. &lt;code&gt;variable_1&lt;/code&gt; is 128 bits. But 128 + 160 = 288 bits. It can't fit in the 96 bits remaining space. (256-160). Then, &lt;code&gt;variable_1&lt;/code&gt; will be stored in slot 1. &lt;code&gt;variable_2&lt;/code&gt; is a 256 bits length. It will be stored in slot 2 because it can't fit in the slot 1 (128 bits remaining space). &lt;code&gt;address_2&lt;/code&gt; will be in slot 3 because the slot 2 is full. The &lt;code&gt;variable_3&lt;/code&gt; will be in slot 4 because the slot 3 has already 160 bits reserved (96 remaining).&lt;/p&gt;

&lt;p&gt;To optimise this version, we can adjust the variable as follow :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uint128 variable_1
uint128 variable_3
uint256 variable_2
address address_1
address address_2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, there is 4 slots taken while the non-optimised version has 5 slots taken. We have saved 32 bytes and prevent unnecessary computation.&lt;/p&gt;




&lt;h3&gt;
  
  
  Loop through an array &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Arrays are quite common nowadays and it's pretty straightforward to read values from them with a for-loop.&lt;br&gt;
If you have guessed where I'm going by saying that, it means you read carefully the introduction.&lt;br&gt;
If you read an array which is a state variable, looping inside the array without caching it into a memory variable cost you more gas.&lt;/p&gt;

&lt;p&gt;In the following example, you can see that for a 9-length array, we spent 83037 gas in the un-optimised version and only 56475 in the most optimised&lt;/p&gt;

&lt;p&gt;My advice: Avoid looping through an array that has a dynamic length. The gas consumption increases overtime and it will become a very expensive process.&lt;/p&gt;

&lt;p&gt;(Try it on Remix)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: GPL-3.0

pragma solidity &amp;gt;=0.7.0 &amp;lt;0.9.0;

contract GasTest {
    uint[] public arrayTest;
    uint public sumArray;

    constructor(){
        arrayTest = [1,2,3,4,5,6,7,8,9];
    }

    /**
    * Keep reading the value of the array from the state variable
    * Keep writing the result in the state variable sumArray
    * Bad idea
    * Gas cost = 83037 
    */
    function calculateSum() external {
        for(uint i = 0; i&amp;lt;arrayTest.length; i++){
            sumArray += arrayTest[i];
        }
    }

    /**
    * Keep reading the value of the array from the state variable
    * Caching the sum in the memory. Write only once in the state variable
    * Not an excellent idea
    * Gas cost = 58087 
    */
    function calculateSum2() external {
        uint _sumArray = 0;
        for(uint i = 0; i&amp;lt;arrayTest.length; i++){
            _sumArray += arrayTest[i];
        }
        sumArray = _sumArray;
    }

    /**
    * Caching the array in the memory
    * Caching the sum in the memory. Write only once in the state variable
    * Excellent idea
    * Gas cost = 56475 
    */
    function calculateSum3() external {
        uint _sumArray = 0;
        uint[] memory _arrayTest = arrayTest;
        for(uint i = 0; i&amp;lt;_arrayTest.length; i++){
            _sumArray += _arrayTest[i];
        }
        sumArray = _sumArray;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Libraries &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If you have many smart contracts using the same functionalities, you should extract all these functionalities to a library and deploy it. &lt;br&gt;
Now, all the smart contracts can reference the deployed library instead of deploying the same code again and again and increase the bytecode length.&lt;br&gt;
Because it's a deployed library, make sure that all your functions are &lt;code&gt;external&lt;/code&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Events &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If you have data created on a smart contract but does not need to be read after by the smart contract, then events are a good candidate. Events consume less gas than a state variable.&lt;/p&gt;


&lt;h3&gt;
  
  
  Computed Values &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Sometimes, you need to store values into the smart contract (hashes for example) and you need to compute this value. My advice is to compute this value off chain and instantiate your smart contract with the computed value. (Remember: The less OPCODE you have, the better optimisation you will get)&lt;/p&gt;


&lt;h3&gt;
  
  
  Constants &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You can have some constant values in your state variables that won't change. Constant values can be useful for gas optimisation.&lt;/p&gt;

&lt;p&gt;Here an example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read state variable with const: 21420 gas&lt;/li&gt;
&lt;li&gt;Read state variable without const: 23541 gas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Try it on Remix)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: GPL-3.0

pragma solidity &amp;gt;=0.7.0 &amp;lt;0.9.0;

contract GasTestConst {
    //Gas cost : 21420 
    address public constant CONST_ADDR = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
}

contract GasTestNoConst {
    //Gas Cost: 23541
    address public addr = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can say that &lt;code&gt;immutable&lt;/code&gt; works the same as &lt;code&gt;const&lt;/code&gt;. The only difference between &lt;code&gt;immutable&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; is that you can initialise the value of the &lt;code&gt;immutable&lt;/code&gt; variable into the constructor.&lt;/p&gt;




&lt;h3&gt;
  
  
  Error Handling &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;When you use &lt;code&gt;require&lt;/code&gt;, you pass the error reason if the condition is not met. But very long string cost more gas.&lt;br&gt;
Using a custom error cost less gas. For the example below, I put the same string. &lt;br&gt;
Remember that with custom error, you should log the value.&lt;/p&gt;

&lt;p&gt;The gas cost is just slightly different but after a while, it saves some money.&lt;/p&gt;

&lt;p&gt;(Try it on Remix)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: GPL-3.0

pragma solidity &amp;gt;=0.7.0 &amp;lt;0.9.0;

contract GasTestError {

    error CustomError(string message);

    //Gas cost: 21977 
    function testRequire(uint _val) public pure {
       require(_val &amp;lt;= 2, "Sorry but your value does not meet the requirement. Please select a value between 0 and 2. Otherwise... Good bye");
       //process
    }

    //Gas cost: 21955 
    function testError(uint _val) public pure {
       if(_val &amp;gt; 2){
           revert CustomError("Sorry but your value does not meet the requirement. Please select a value between 0 and 2. Otherwise... Good bye");
       }
       //process
   }
}

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

&lt;/div&gt;






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

&lt;p&gt;This list is not exhaustive. We could also add the EIP 1167 for the Proxy contract but I don't want to explain advanced technique. Try these 10 tips and play with your smart contract. The goal is to save some gas with basic optimisation for beginners.&lt;br&gt;
If you have any question, please comment below ;)&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>solidity</category>
      <category>blokchain</category>
      <category>programming</category>
    </item>
    <item>
      <title>Ethereum2.0 : Rebranding</title>
      <dc:creator>Akim B. (mousticke.eth)</dc:creator>
      <pubDate>Wed, 26 Jan 2022 21:48:11 +0000</pubDate>
      <link>https://dev.to/mousticke/ethereum20-rebranding-17e2</link>
      <guid>https://dev.to/mousticke/ethereum20-rebranding-17e2</guid>
      <description>&lt;p&gt;When Ethereum2.0 is coming? Now the sort answer is: &lt;code&gt;Never&lt;/code&gt;&lt;br&gt;
But hold on! Let's explain a bit. &lt;br&gt;
Caveat: I won't detail too much about the upgrade of the second layer. There is a lot of articles explaining the general purpose of the Beacon Chain, The Merge and The Sharding. What I want you to be aware, is the naming convention used in the Ethereum Network. More specifically since January 24th 2022.&lt;/p&gt;

&lt;p&gt;Because I mentioned the three milestones of Eth2.0, let me give you a short description for them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definitions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beacon Chain
&lt;/h3&gt;

&lt;p&gt;Introduce the proof of stake consensus for Ethereum network. It will be the backbone of the new network upgrade.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Merge
&lt;/h3&gt;

&lt;p&gt;Mark the end of the proof of work. Because the Beacon Chain is a separated network. But in the end, the Mainnet is going to be merged with the Beacon Chain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sharding
&lt;/h3&gt;

&lt;p&gt;Act as a horizontal scaling of the Ethereum network. Each node will run a chunk of the entire blockchain. The big advantage stays in the hardware consumptions/requirements. This will improve the number of transactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Network upgrade
&lt;/h2&gt;

&lt;p&gt;Since the end of 2020, we hear a lot of Ethereum 2.0. But the engineers of Ethereum don't use this term anymore and prefer to say, "Execution Layer" for Eth1 and "Consensus Layer" for Eth2.&lt;br&gt;
The two layers is &lt;strong&gt;&lt;code&gt;Ethereum&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The roadmap of Ethereum consists in scaling the network and introduce the proof of stake consensus. This is the roadmap of Eth2.0. In order to be shipped, the release will take some time. There is, at this time, the beacon chain shipped. We are waiting for the merge in 2022 and the sharding in 2023.&lt;/p&gt;

&lt;p&gt;Ok but at this point, why can't we say Ethereum 2.0?&lt;br&gt;
&lt;u&gt;1 - Prevent scam:&lt;/u&gt; Malicious actors will take advantage of the new name to create an ETH2 token and tell to the users to change between their current ETH to the "new" ETH because it will be deprecated.&lt;br&gt;
&lt;u&gt;2 - Staking:&lt;/u&gt; Staking in the Beacon chain is allowed with ETH and reward are given in ETH. There is no ETH2 rewards. This can create a confusion and we can join the first point of a potential scam.&lt;br&gt;
&lt;u&gt;3 - Models:&lt;/u&gt; Eth2 is not a new model. It's just an upgrade. But the overall architecture remains.&lt;/p&gt;

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

&lt;p&gt;Keep in mind that the only network that exists is Ethereum. But the Ethereum network is a merge between the execution layer (Eth1) and the consensus layer (Eth2)&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>opensource</category>
      <category>news</category>
      <category>ethereum</category>
    </item>
    <item>
      <title>Vulnerability exploit : Access to the private state variable in a Smart Contract</title>
      <dc:creator>Akim B. (mousticke.eth)</dc:creator>
      <pubDate>Thu, 30 Dec 2021 01:40:14 +0000</pubDate>
      <link>https://dev.to/mousticke/vulnerabilty-exploit-access-to-the-private-state-variable-in-a-smart-contract-3h5k</link>
      <guid>https://dev.to/mousticke/vulnerabilty-exploit-access-to-the-private-state-variable-in-a-smart-contract-3h5k</guid>
      <description>&lt;p&gt;When we think about &lt;code&gt;private&lt;/code&gt; data in general, we think that any program or software interacting with our smart-contract cannot access to this variable.&lt;br&gt;
Usually, when we have a &lt;code&gt;private&lt;/code&gt; variable in an OOP, we use a getter and a setter for manipulating or reading the data.&lt;br&gt;
Sometimes, we can see that the &lt;code&gt;private&lt;/code&gt; visibility is used to store some sensitive data and we don't want anyone to read that data.&lt;/p&gt;

&lt;p&gt;Let's say in our smart contract, we define a &lt;code&gt;private&lt;/code&gt; state variable to store a password, a secret key or whatever. So that nobody can read or modify the data.&lt;br&gt;
But it doesn't mean that we can't access to this data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A private state variable can be read&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's jump into the code and some explanation&lt;br&gt;
You can go to the github repo (Link below in the Conclusion) to get the source code or follow along with me.&lt;/p&gt;
&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;NodeJS &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Truffle&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; truffle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://web3js.readthedocs.io/en/v1.5.2/getting-started.html#adding-web3-js" rel="noopener noreferrer"&gt;Web3JS&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;web3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;a href="https://trufflesuite.com/ganache/" rel="noopener noreferrer"&gt;Ganache&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Instantiate Truffle project
&lt;/h1&gt;

&lt;p&gt;First, create a truffle project within a directory with the following command :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create a contract&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle create contract TestPrivate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Code
&lt;/h1&gt;

&lt;p&gt;Now we have a contract created, copy paste this code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity &amp;gt;=0.4.22 &amp;lt;0.9.0;

contract TestPrivate {

  bool public slot_boolean = true;        // → slot 0 : 1 byte
  address public owner = msg.sender;                   // → slot 0 : 20 bytes
  uint256 public slot_uint256 = 1000;     // → slot 1 : 32 bytes
  uint[2] public data;                    // → slot 2 : 32 bytes and slot 3 : 32 bytes (one slot per element)
  bytes32 private secret_data;            // → slot 4 : 32 bytes

  struct User{
    uint id;
    uint8 role;
    address userAddress;
    bytes32 password;
  }

  User[] private users;                // → slot 5 starts at keccak(5) for first user
                                      // → second user at keccack(5) + (3 → slot used for the storing one struct of user)

  constructor(bytes32 _secret_data) {
    secret_data = _secret_data;
  }

  function enrollUser(uint8 _role, bytes32 _password) external {
    User memory user = User({
      id: users.length,
      role: _role,
      userAddress: msg.sender,
      password: _password
    });

    users.push(user);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have the code, let's see how the EVM stores the variables&lt;/p&gt;

&lt;h1&gt;
  
  
  Slots in the EVM
&lt;/h1&gt;

&lt;p&gt;The EVM will store the state variables inside an array in a compact way. That means multiple values can use the same slot. A slot can store up to 32bytes.&lt;br&gt;
So when a variable in the slot is lower than 32 bytes, if the next variable can fit in the remaining space, it will be stored in the same slot.&lt;br&gt;
(It's better to use 32 bytes variables for gas usage but it's another subject).&lt;/p&gt;

&lt;p&gt;Let's see in our code, how is it stored.&lt;br&gt;
Our first variable is a boolean set to true. It will be stored in the slot 0 and takes 1 byte.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;slot&lt;/th&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;32 bytes slot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000000000000000000000000000000000000000000001&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Next, we have an address type which is 20 bytes size. But in the slot 0, we still have enough space to store 20 bytes.&lt;br&gt;
So we compact two variables inside this slot&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;slot&lt;/th&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;32 bytes slot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;address &amp;amp; bool&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000aC86db09Aa6756D9606d638bFb3a3A0f7669850401&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So we now have 11 bytes remaining space. (20 + 1 = 21 bytes used)&lt;/p&gt;

&lt;p&gt;After that, we have a uint256 with a value of 1000 (10). A uint256 is unsigned integer with a size of 256 bits (32 bytes). So the entire slot 1 will store this variable.&lt;br&gt;
So the storage will be :&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;slot&lt;/th&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;32 bytes slot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;address &amp;amp; bool&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000aC86db09Aa6756D9606d638bFb3a3A0f7669850401&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;uint256 (1000)&lt;/td&gt;
&lt;td&gt;0x00000000000000000000000000000000000000000000000000000000000003e8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;If this uint was a uint64, whe would store 8 bytes inside the slot 0 because we have enough space. But if the slot 0 was full, we would store the data inside the next slot with a remaining space of 24 bytes (32 bytes - 8 bytes). The EVM does some operation to convert a 2^(3+k) (where 0&amp;lt;k&amp;lt;3) bytes data to fit inside a 32 bytes slot by adding some 0 in front of the data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then we have an array of 2 elements of uint256. Each element is stored inside a slot. Because one element is a 32 bytes size, we use 2 slots for the entire array.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;slot&lt;/th&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;32 bytes slot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;address &amp;amp; bool&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000aC86db09Aa6756D9606d638bFb3a3A0f7669850401&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;uint256 (1000)&lt;/td&gt;
&lt;td&gt;0x00000000000000000000000000000000000000000000000000000000000003e8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;uint256(0)&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;uint256(1)&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We store the &lt;code&gt;private&lt;/code&gt; bytes32 inside the slot 4.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;slot&lt;/th&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;32 bytes slot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;address &amp;amp; bool&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000aC86db09Aa6756D9606d638bFb3a3A0f7669850401&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;uint256 (1000)&lt;/td&gt;
&lt;td&gt;0x00000000000000000000000000000000000000000000000000000000000003e8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;uint256(0)&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;uint256(1)&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;bytes32&lt;/td&gt;
&lt;td&gt;0x0000000000000000000000000000000000000000000000000000000000000000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Next we have a struct of User. Inside that struct, we have :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; id - uint (32 bytes)&lt;/li&gt;
&lt;li&gt; role - uint8 (1 byte)&lt;/li&gt;
&lt;li&gt; userAddress - address (20 bytes)&lt;/li&gt;
&lt;li&gt; password - bytes32 (32 bytes)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So inside the array of User, we start to store at the slot 5. To know where to find the first user, we convert the number of the slot into a hash (keccak256). If we access to this slot, we have the id. Then if we increment the hash by one we access to the next slot which contains the role (1 byte) and the address (20 bytes).&lt;br&gt;
If we increment the hash by 2, we access to the third slot, which contains the password.&lt;br&gt;
If you want to access to the id of the second user, you increment the hash by 3 and so on...&lt;/p&gt;
&lt;h1&gt;
  
  
  Deploy the contract
&lt;/h1&gt;

&lt;p&gt;Now let's deploy the contract.&lt;br&gt;
We have a constructor that takes a parameter of a bytes32. Let's pass this argument &lt;code&gt;0x0000000000000000000000000000000000007365637265742069732068657265&lt;/code&gt;.&lt;br&gt;
It's the string &lt;code&gt;secret is here&lt;/code&gt; in hex representation.&lt;/p&gt;

&lt;p&gt;To deploy the contract, we first need to create the &lt;code&gt;migration&lt;/code&gt; file for truffle. For that, you need to compile the smart contract because we need to access to the artifact. Then create a file inside the migrations folder.&lt;/p&gt;

&lt;p&gt;Run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  truffle compile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output from the compile command should look like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;truffle compile

Compiling your contracts...
&lt;span class="o"&gt;===========================&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Compiling .&lt;span class="se"&gt;\c&lt;/span&gt;ontracts&lt;span class="se"&gt;\M&lt;/span&gt;igrations.sol
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Compiling .&lt;span class="se"&gt;\c&lt;/span&gt;ontracts&lt;span class="se"&gt;\T&lt;/span&gt;estPrivate.sol
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Artifacts written to D:&lt;span class="se"&gt;\D&lt;/span&gt;ocuments&lt;span class="se"&gt;\D&lt;/span&gt;evelopment&lt;span class="se"&gt;\E&lt;/span&gt;ther&lt;span class="se"&gt;\s&lt;/span&gt;ecurity&lt;span class="se"&gt;\s&lt;/span&gt;olidity-private-data&lt;span class="se"&gt;\b&lt;/span&gt;uild&lt;span class="se"&gt;\c&lt;/span&gt;ontracts
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Compiled successfully using:
   - solc: 0.8.9+commit.e5eed63a.Emscripten.clang
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;2_deploy_TestPrivate.js&lt;/code&gt; file inside the migrations directory&lt;/p&gt;

&lt;p&gt;Then add this code inside the file &lt;code&gt;2_deploy_TestPrivate.js&lt;/code&gt;&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;TestPrivate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;artifacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TestPrivate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deployer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accounts&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;secretUse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x0000000000000000000000000000000000007365637265742069732068657265&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//secret is here&lt;/span&gt;
  &lt;span class="nx"&gt;deployer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;TestPrivate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secretUse&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;After that you need to check if you have a network enabled inside your truffle config. (In my case, I will run a local network with ganache)&lt;br&gt;
Your truffle config should look like this :&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="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;ganache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Localhost (default: none)&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7545&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Standard Ethereum port (default: none)&lt;/span&gt;
      &lt;span class="na"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Any network (default: none)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// Set default mocha options here, use special reporters etc.&lt;/span&gt;
  &lt;span class="na"&gt;mocha&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// timeout: 100000&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// Configure your compilers&lt;/span&gt;
  &lt;span class="na"&gt;compilers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;solc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.8.9&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Fetch exact version from solc-bin (default: truffle's version)&lt;/span&gt;
      &lt;span class="c1"&gt;// docker: true,        // Use "0.5.1" you've installed locally with docker (default: false)&lt;/span&gt;
      &lt;span class="c1"&gt;// settings: {          // See the solidity docs for advice about optimization and evmVersion&lt;/span&gt;
      &lt;span class="c1"&gt;//  optimizer: {&lt;/span&gt;
      &lt;span class="c1"&gt;//    enabled: false,&lt;/span&gt;
      &lt;span class="c1"&gt;//    runs: 200&lt;/span&gt;
      &lt;span class="c1"&gt;//  },&lt;/span&gt;
      &lt;span class="c1"&gt;//  evmVersion: "byzantium"&lt;/span&gt;
      &lt;span class="c1"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have all the setup done, after running the command &lt;code&gt;truffle migrate --network ganache&lt;/code&gt;, you should see the following output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;truffle migrate &lt;span class="nt"&gt;--network&lt;/span&gt; ganache

Compiling your contracts...
&lt;span class="o"&gt;===========================&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Compiling .&lt;span class="se"&gt;\c&lt;/span&gt;ontracts&lt;span class="se"&gt;\M&lt;/span&gt;igrations.sol
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Compiling .&lt;span class="se"&gt;\c&lt;/span&gt;ontracts&lt;span class="se"&gt;\T&lt;/span&gt;estPrivate.sol
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Artifacts written to D:&lt;span class="se"&gt;\D&lt;/span&gt;ocuments&lt;span class="se"&gt;\D&lt;/span&gt;evelopment&lt;span class="se"&gt;\E&lt;/span&gt;ther&lt;span class="se"&gt;\s&lt;/span&gt;ecurity&lt;span class="se"&gt;\s&lt;/span&gt;olidity-private-data&lt;span class="se"&gt;\b&lt;/span&gt;uild&lt;span class="se"&gt;\c&lt;/span&gt;ontracts
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Compiled successfully using:
   - solc: 0.8.9+commit.e5eed63a.Emscripten.clang



Starting migrations...
&lt;span class="o"&gt;======================&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Network name:    &lt;span class="s1"&gt;'ganache'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Network &lt;span class="nb"&gt;id&lt;/span&gt;:      5777
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Block gas limit: 6721975 &lt;span class="o"&gt;(&lt;/span&gt;0x6691b7&lt;span class="o"&gt;)&lt;/span&gt;


1_initial_migration.js
&lt;span class="o"&gt;======================&lt;/span&gt;

   Deploying &lt;span class="s1"&gt;'Migrations'&lt;/span&gt;
   &lt;span class="nt"&gt;----------------------&lt;/span&gt;
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; transaction &lt;span class="nb"&gt;hash&lt;/span&gt;:    0xb6767a41e6067e2ec91eb8160df8a52064366aaa89768e7377dd6a5f9fc312ac
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Blocks: 0            Seconds: 0
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; contract address:    0xA441f0E978c08E70c3249d97Dd542E7E37bEc06D
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; block number:        618
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; block timestamp:     1640659167
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; account:             0x009d6EF647f472b543A6057b443a72Dff6e61c7a
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; balance:             96.52405552
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; gas used:            248842 &lt;span class="o"&gt;(&lt;/span&gt;0x3cc0a&lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; gas price:           20 gwei
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; value sent:          0 ETH
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; total cost:          0.00497684 ETH


   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Saving migration to chain.
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Saving artifacts
   &lt;span class="nt"&gt;-------------------------------------&lt;/span&gt;
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Total cost:          0.00497684 ETH


2_deploy_TestPrivate.js
&lt;span class="o"&gt;=======================&lt;/span&gt;

   Deploying &lt;span class="s1"&gt;'TestPrivate'&lt;/span&gt;
   &lt;span class="nt"&gt;-----------------------&lt;/span&gt;
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; transaction &lt;span class="nb"&gt;hash&lt;/span&gt;:    0x764f973c29ed5937b26728f80689387fcf99b38d96a635bcdf43edc17a331c1b
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Blocks: 0            Seconds: 0
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; contract address:    0xd3a66714eB418B33f78c46FbC1B4996c6dE2F705
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; block number:        620
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; block timestamp:     1640659168
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; account:             0x009d6EF647f472b543A6057b443a72Dff6e61c7a
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; balance:             96.5160722
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; gas used:            356653 &lt;span class="o"&gt;(&lt;/span&gt;0x5712d&lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; gas price:           20 gwei
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; value sent:          0 ETH
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; total cost:          0.00713306 ETH


   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Saving migration to chain.
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Saving artifacts
   &lt;span class="nt"&gt;-------------------------------------&lt;/span&gt;
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Total cost:          0.00713306 ETH


Summary
&lt;span class="o"&gt;=======&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Total deployments:   2
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Final cost:          0.0121099 ETH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In ganache, we can see our contract deployed (You need to add the truffle config file)&lt;/p&gt;

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

&lt;p&gt;Inside your json file of the previously compiled contract, you should see this object&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"networks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"5777"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"events"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0xd3a66714eB418B33f78c46FbC1B4996c6dE2F705"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"transactionHash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x764f973c29ed5937b26728f80689387fcf99b38d96a635bcdf43edc17a331c1b"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now our contract is deployed and ready to use, we can add some data inside the users array.&lt;/p&gt;

&lt;h1&gt;
  
  
  Interact with the smart contract
&lt;/h1&gt;

&lt;p&gt;Since we have a client (Ganache), we run the command &lt;code&gt;truffle console&lt;/code&gt;&lt;br&gt;
See if it works by returning the list of the accounts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;accounts &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getAccounts&lt;span class="o"&gt;()&lt;/span&gt;
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; accounts
&lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="s1"&gt;'0x009d6EF647f472b543A6057b443a72Dff6e61c7a'&lt;/span&gt;,
  &lt;span class="s1"&gt;'0x4EBE31e37c016253DE9B8994514Da6cBCB57f0a5'&lt;/span&gt;,
  &lt;span class="s1"&gt;'0xC66A8fBAF9F95CCe86AefB8e713029E2aa9c7E8d'&lt;/span&gt;,
  &lt;span class="s1"&gt;'0xF22f46120471166fb7029990D4eCBaCb63e575B4'&lt;/span&gt;,
  &lt;span class="s1"&gt;'0x7B4794aD644543b80b71c1243185E37AEA50B403'&lt;/span&gt;,
  &lt;span class="s1"&gt;'0xbe8eC832Ea864366F789AB1458358e4506228075'&lt;/span&gt;,
  &lt;span class="s1"&gt;'0x108BdEa3473a7488377C9FbE5b12078bf311Ca16'&lt;/span&gt;,
  &lt;span class="s1"&gt;'0xbdEe79e2C8CA3311B9C8531410f09567F22F4FEd'&lt;/span&gt;,
  &lt;span class="s1"&gt;'0x579Ed8B42541E0877D9e2425D32a67127f22b0A3'&lt;/span&gt;,
  &lt;span class="s1"&gt;'0xA3AD8DE6b1BDe5DacF715E4008866b3c12a5def0'&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's create an instance of the smart contract&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;instance &lt;span class="o"&gt;=&lt;/span&gt; await TestPrivate.deployed&lt;span class="o"&gt;()&lt;/span&gt;
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; instance
 ...
 contractName: &lt;span class="s1"&gt;'TestPrivate'&lt;/span&gt;,
      abi: &lt;span class="o"&gt;[&lt;/span&gt;Array],
      metadata: ...
 ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Access to the slot
&lt;/h1&gt;

&lt;p&gt;Now we have our smart contract instance, let's see how we access to the slots.&lt;/p&gt;

&lt;p&gt;First we need the address of the smart contract&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;address &lt;span class="o"&gt;=&lt;/span&gt; await instance.address
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; address
&lt;span class="s1"&gt;'0xd3a66714eB418B33f78c46FbC1B4996c6dE2F705'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will use our address to get the data inside the storage with web3&lt;/p&gt;

&lt;h2&gt;
  
  
  Slot 0
&lt;/h2&gt;

&lt;p&gt;For the slot 0, we have&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;instance &lt;span class="o"&gt;=&lt;/span&gt; await TestPrivate.deployed&lt;span class="o"&gt;()&lt;/span&gt;
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;address &lt;span class="o"&gt;=&lt;/span&gt; await instance.address
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; address
&lt;span class="s1"&gt;'0xB3884D48eA4f9CbC6bCE90E3D58d193C6c6d719C'&lt;/span&gt;
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;slot0 &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getStorageAt&lt;span class="o"&gt;(&lt;/span&gt;address, 0, console.log&lt;span class="o"&gt;)&lt;/span&gt;
null 0x9d6ef647f472b543a6057b443a72dff6e61c7a01
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; slot0
&lt;span class="s1"&gt;'0x9d6ef647f472b543a6057b443a72dff6e61c7a01'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see our owner address &lt;code&gt;9d6ef647f472b543a6057b443a72dff6e61c7a&lt;/code&gt; and our boolean value &lt;code&gt;01&lt;/code&gt;&lt;br&gt;
You can check the owner address&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; await instance.owner&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="s1"&gt;'0x009d6EF647f472b543A6057b443a72Dff6e61c7a'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Slot 1
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;slot1 &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getStorageAt&lt;span class="o"&gt;(&lt;/span&gt;address, 1, console.log&lt;span class="o"&gt;)&lt;/span&gt;
null 0x03e8
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; slot1
&lt;span class="s1"&gt;'0x03e8'&lt;/span&gt;
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see the uint256 value 1000 in hex.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; parseInt&lt;span class="o"&gt;(&lt;/span&gt;0x3e8, 10&lt;span class="o"&gt;)&lt;/span&gt;
1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Slot 2 and 3
&lt;/h2&gt;

&lt;p&gt;As I said earlier, the slot 2 and 3 contains the value of the uint256 array. Each value are stored in one slot due to their size.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;slot2 &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getStorageAt&lt;span class="o"&gt;(&lt;/span&gt;address, 2, console.log&lt;span class="o"&gt;)&lt;/span&gt;
null 0x0
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; slot2
&lt;span class="s1"&gt;'0x0'&lt;/span&gt;
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;slot3 &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getStorageAt&lt;span class="o"&gt;(&lt;/span&gt;address, 3, console.log&lt;span class="o"&gt;)&lt;/span&gt;
null 0x0
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; slot3
&lt;span class="s1"&gt;'0x0'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Slot 4
&lt;/h2&gt;

&lt;p&gt;Here comes the funny part. We have a &lt;code&gt;private&lt;/code&gt; state variable. Let's see what we have&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;slot4 &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getStorageAt&lt;span class="o"&gt;(&lt;/span&gt;address, 4, console.log&lt;span class="o"&gt;)&lt;/span&gt;
null 0x7365637265742069732068657265
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; slot4
&lt;span class="s1"&gt;'0x7365637265742069732068657265'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see the hex value &lt;code&gt;0x7365637265742069732068657265&lt;/code&gt;. Since it is a bytes32 state variable, let's convert into an alphabet representation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;asciiPrivateData &lt;span class="o"&gt;=&lt;/span&gt; await web3.utils.toAscii&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'0x7365637265742069732068657265'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; asciiPrivateData
&lt;span class="s1"&gt;'secret is here'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see that we can clearly read the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slot 5
&lt;/h2&gt;

&lt;p&gt;In the user array, we first add 2 users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; await instance.enrollUser&lt;span class="o"&gt;(&lt;/span&gt;1, web3.utils.toHex&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"secret user1"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  tx: &lt;span class="s1"&gt;'0xa9c1e069d453a41cce948f3c6779dc8d02a3ee2e50b3b4cba9866bc5f4c4aa4a'&lt;/span&gt;,
  receipt: &lt;span class="o"&gt;{&lt;/span&gt;
    transactionHash: &lt;span class="s1"&gt;'0xa9c1e069d453a41cce948f3c6779dc8d02a3ee2e50b3b4cba9866bc5f4c4aa4a'&lt;/span&gt;,
    transactionIndex: 0,
    blockHash: &lt;span class="s1"&gt;'0x05ec32043c20202580f971711715d2c4c3483723703d3879b859080c92626ff0'&lt;/span&gt;,
    blockNumber: 626,
    from: &lt;span class="s1"&gt;'0x009d6ef647f472b543a6057b443a72dff6e61c7a'&lt;/span&gt;,
    to: &lt;span class="s1"&gt;'0xb3884d48ea4f9cbc6bce90e3d58d193c6c6d719c'&lt;/span&gt;,
    gasUsed: 87357,
    cumulativeGasUsed: 87357,
    contractAddress: null,
    logs: &lt;span class="o"&gt;[]&lt;/span&gt;,
    status: &lt;span class="nb"&gt;true&lt;/span&gt;,
    logsBloom: &lt;span class="s1"&gt;'0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'&lt;/span&gt;,
    rawLogs: &lt;span class="o"&gt;[]&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  logs: &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; await instance.enrollUser&lt;span class="o"&gt;(&lt;/span&gt;2, web3.utils.toHex&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"secret user2"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  tx: &lt;span class="s1"&gt;'0xedef6f68f3e742b6ec41e10e7256f1fceba84b247f2b1d83ec66b367f04511bb'&lt;/span&gt;,
  receipt: &lt;span class="o"&gt;{&lt;/span&gt;
    transactionHash: &lt;span class="s1"&gt;'0xedef6f68f3e742b6ec41e10e7256f1fceba84b247f2b1d83ec66b367f04511bb'&lt;/span&gt;,
    transactionIndex: 0,
    blockHash: &lt;span class="s1"&gt;'0x4f6f86923646c4103d9b5eaf413f0ef2cebe175ea6b550fb971fd48a08ff52e6'&lt;/span&gt;,
    blockNumber: 627,
    from: &lt;span class="s1"&gt;'0x009d6ef647f472b543a6057b443a72dff6e61c7a'&lt;/span&gt;,
    to: &lt;span class="s1"&gt;'0xb3884d48ea4f9cbc6bce90e3d58d193c6c6d719c'&lt;/span&gt;,
    gasUsed: 91557,
    cumulativeGasUsed: 91557,
    contractAddress: null,
    logs: &lt;span class="o"&gt;[]&lt;/span&gt;,
    status: &lt;span class="nb"&gt;true&lt;/span&gt;,
    logsBloom: &lt;span class="s1"&gt;'0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'&lt;/span&gt;,
    rawLogs: &lt;span class="o"&gt;[]&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  logs: &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have the 2 user, let's run our methods to get the storage at the slot 5&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;slot5 &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getStorageAt&lt;span class="o"&gt;(&lt;/span&gt;address, 5, console.log&lt;span class="o"&gt;)&lt;/span&gt;
null 0x02
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; slot5
&lt;span class="s1"&gt;'0x02'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see that we have 2 User inside our array. The first user should be stored at the hash of the slot 5&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;hashFirstUser &lt;span class="o"&gt;=&lt;/span&gt; await web3.utils.soliditySha3&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;: &lt;span class="s2"&gt;"uint"&lt;/span&gt;, value: 5&lt;span class="o"&gt;})&lt;/span&gt;
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; hashFirstUser
&lt;span class="s1"&gt;'0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0'&lt;/span&gt;
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, get the first user id&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;slot_user1_id &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getStorageAt&lt;span class="o"&gt;(&lt;/span&gt;address, hashFirstUser, console.log&lt;span class="o"&gt;)&lt;/span&gt;
null 0x0
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; slot_user1_id
&lt;span class="s1"&gt;'0x0'&lt;/span&gt;
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should equal 0 because the id is the length of the array before we push the struct.&lt;/p&gt;

&lt;p&gt;To get the user role and address, we need to read the next slot by incrementing the hash by one&lt;br&gt;
&lt;code&gt;0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0&lt;/code&gt; → &lt;code&gt;0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db1&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;slot_user1_roleAndAddress &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getStorageAt&lt;span class="o"&gt;(&lt;/span&gt;address, &lt;span class="s1"&gt;'0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db1'&lt;/span&gt;, console.log&lt;span class="o"&gt;)&lt;/span&gt;
null 0x9d6ef647f472b543a6057b443a72dff6e61c7a01
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; slot_user1_roleAndAddress
&lt;span class="s1"&gt;'0x9d6ef647f472b543a6057b443a72dff6e61c7a01'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see the role &lt;code&gt;01&lt;/code&gt; and the msg.sender value. (Which is the same as the owner in this case) &lt;code&gt;0x9d6ef647f472b543a6057b443a72dff6e61c7a&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, we access to the password of the user by incrementing again the hash by 2&lt;br&gt;
&lt;code&gt;0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0&lt;/code&gt; → &lt;code&gt;0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db2&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;slot_user1_password &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getStorageAt&lt;span class="o"&gt;(&lt;/span&gt;address, &lt;span class="s1"&gt;'0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db2'&lt;/span&gt;, console.log&lt;span class="o"&gt;)&lt;/span&gt;
null 0x7365637265742075736572310000000000000000000000000000000000000000
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; slot_user1_password
&lt;span class="s1"&gt;'0x7365637265742075736572310000000000000000000000000000000000000000'&lt;/span&gt;
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; await web3.utils.toAscii&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'0x7365637265742075736572310000000000000000000000000000000000000000'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="s1"&gt;'secret user1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can clearly see the password of the user even though the state variable is &lt;code&gt;private&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can guess that if you want to see the data of the user 2, you need to increment the hash by 3 (3 slots for one user due to our structure)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;slot_user2_id &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getStorageAt&lt;span class="o"&gt;(&lt;/span&gt;address, &lt;span class="s1"&gt;'0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db3'&lt;/span&gt;, console.log&lt;span class="o"&gt;)&lt;/span&gt;
null 0x01
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; slot_user2_id
&lt;span class="s1"&gt;'0x01'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can access to the password of the second user by incrementing the hash by 5&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;slot_user2_password &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getStorageAt&lt;span class="o"&gt;(&lt;/span&gt;address, &lt;span class="s1"&gt;'0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db5'&lt;/span&gt;, console.log&lt;span class="o"&gt;)&lt;/span&gt;
null 0x7365637265742075736572320000000000000000000000000000000000000000
undefined
truffle&lt;span class="o"&gt;(&lt;/span&gt;ganache&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; await web3.utils.toAscii&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'0x7365637265742075736572320000000000000000000000000000000000000000'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="s1"&gt;'secret user2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Do not assume that because you have a &lt;code&gt;private&lt;/code&gt; state variable, we cannot access to the data. The recommendation is :&lt;br&gt;
&lt;strong&gt;Do not store sensitive data on the blockchain.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can get the code here : &lt;a href="https://github.com/Mousticke/solidity-private-data" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>ethereum</category>
      <category>smartcontract</category>
      <category>security</category>
    </item>
  </channel>
</rss>
