RareSkills Blog

Converting Algebraic Circuits to R1CS (Rank One Constraint System)
Converting Algebraic Circuits to R1CS (Rank One Constraint System) This article is explains how to turn a set of arithmetic constraints into Rank One Constraint System (R1CS). The focus of…

How Tornado Cash Works (Line by Line for Devs)
How Tornado Cash Works (Line by Line for Devs) Introduction to Tornado Cash Tornado cash is a cryptocurrency smart contract mixer that enables users to deposit crypto with one address…

Getting a smart contract audit: what you need to know
Getting a smart contract audit: what you need to know A smart contract audit is a review by blockchain security experts to ensure that users will not lose funds due…

ZK-addition-dapp with Noir and Nextjs
ZK-addition-dapp with Noir and Nextjs We will demonstrate a step-by-step exploration of a basic zk-dapp designed for verifying additions. This application enables users to prove that the sum of two…

Web3.js Example. Latest version 4.x. Transfer, Mint and Query the Blockchain
Web3.js Example. Latest version 4.x. Transfer, Mint and Query the Blockchain The newest version of web3.js, 4.x, has just been unveiled. In this guide, we’ll delve into integrating web3.js into…

Understanding smart contract metadata
Understanding smart contract metadata When solidity generates the bytecode for the smart contract to be deployed, it appends metadata about the compilation at the end of the bytecode. We will…

Over 150 interview questions for Ethereum Developers
Over 150 interview questions for Ethereum Developers All of these questions can be answered in three sentences or less. Easy What is the difference between private, internal, public, and external…

Smart Contract Security
Smart Contract Security This article serves as a mini course on smart contract security and provides an extensive list of the issues and vulnerabilities that tend to recur in Solidity…

The initializable smart contract design pattern
The initializable smart contract design pattern Initializers are how upgradeable contracts achieve the behavior of a constructor. When deploying contracts, it’s common to call a constructor to initialize storage variables.…

Wagmi + ReactJS Example: Transfer Crypto and Mint an NFT
Wagmi + ReactJS Example: Transfer Crypto and Mint an NFT In this tutorial, we’ll learn how to build a Web3 Dapp (Decentralized Application) that connects to your crypto wallet, allowing…

Ethereum precompiled contracts
Ethereum precompiled contracts Ethereum precompiles behave like smart contracts built into the Ethereum protocol. The nine precompiles live in addresses 0x01 to 0x09. The utility of precompiles falls into four…

Solidity Mutation Testing
Solidity Mutation Testing Mutation testing is a method to check the quality of the test suite by intentionally introducing bugs into the code and ensuring the tests catch the bug.…

Foundry Unit Tests
Foundry Unit Tests This article will describe how to create unit tests in Solidity using Foundry. We will cover how to test all the state transitions that can occur in…

Solidity Staticcall EIP 214
Solidity Staticcall EIP 214 Staticcall is like a regular Ethereum call except that it reverts if a state change happens. It cannot be used to transfer Ether. Both the EVM…

Openzeppelin Ownable: Use Ownable2Step Instead
Openzeppelin Ownable: Use Ownable2Step Instead The onlyOwner modifier is probably one of the most common patterns in Solidity. In the following example, the function setMessage() can only be called by…

Foundry forge coverage
Foundry forge coverage Visual line coverage report with LCOV If you run “forge coverage” in a foundry project, you’ll get a table showing how much of your lines and branches…

Solidity test internal function
Solidity test internal function To test an internal solidity function, create a child contract that inherits from the contract being tested, wrap the parent contract’s internal function with an external…

Uint256 max value
Uint256 max value The uint256 max value can be obtained with type(uint256).max; which is 115792089237316195423570985008687907853269984665640564039457584007913129639935 or 2²⁵⁶-1. But it’s cleaner and safer to use type(uint256).max. The same can be used…

Solidity Events
Solidity Events Solidity events are the closest thing to a print or console.log statement in Ethereum. We will explain how they work, best practices for events, and go into a…

EIP-2930 – Ethereum access list
EIP-2930 – Ethereum access list Introduction An Ethereum access list transaction enables saving gas on cross-contract calls by declaring in advance which contract and storage slots will be accessed. Up…

EIP-150 and the 63/64 Rule for Gas
EIP-150 and the 63/64 Rule for Gas Introduction EIP-150, or Ethereum Improvement Proposal 150, is a protocol upgrade for the Ethereum blockchain. It was proposed on March 18, 2016, and…

Solidity Signed Integer
Solidity Signed Integer Solidity signed integers enable using negative numbers in a smart contract. This article documents how they are used at the EVM level. Basic familiarity with the EVM…

Verify Signature Solidity in Foundry
Verify Signature Solidity in Foundry Here is a minimal (copy and paste) example of how to safely create and verify ECDSA signatures with OpenZeppelin in the Foundry environment. Contract: Verifier.sol…

Convert gas to USD (Ethereum)
Convert gas to USD (Ethereum) Understanding gas cost can be tricky because there are three components at play: the gas price, the price of ether, and the units of gas.…

EIP-3448 MetaProxy Standard: Minimal Proxy with support for immutable metadata
EIP-3448 MetaProxy Standard: Minimal Proxy with support for immutable metadata The minimal proxy standard allows us to parameterize the creation of the clone, but this requires an extra initialization transaction.…

Governance Contract in Solidity
Governance Contract in Solidity The pattern of governance many DeFi applications follows is heavily inspired by Compound Finance’s implementation. Although, there isn’t an Ethereum Improvement Proposal related to create a…

ERC20 Snapshot
ERC20 Snapshot ERC20 Snapshot solves the problem of double voting. If votes are weighed by the number of tokens someone holds, then a malicious actor can use their tokens to…