Cross Program Invocation In Anchor

Cross Program Invocation In Anchor Cross Program Invocation (CPI) is Solana’s terminology for a program calling the public function of another program. We’ve already done CPI before when we sent a transfer SOL transaction to the system program. Here is the relevant snippet by way of reminder: pub fn send_sol(ctx: Context<SendSol>, amount: u64) -> Result<()> […]

Reading Another Anchor Program’s Account Data On Chain

Reading Another Anchor Program’s Account Data On Chain In Solidity, reading another contract’s storage requires calling a view function or the storage variable being public. In Solana, an off-chain client can read a storage account directly. This tutorial shows how an on-chain Solana program can read the data in an account it does not own. […]

#[derive(Accounts)] in Anchor: different kinds of accounts

[derive(Accounts)] in Anchor: different kinds of accounts #[derive(Accounts)] in Solana Anchor is an attribute-like macro for structs that holds references to all the accounts the function will access during its execution. In Solana, every account the transaction will access must be specified in advance One reason Solana is so fast is that it executes transactions […]

Modifying accounts using different signers

Modifying accounts using different signers In our Solana tutorials thus far, we’ve only had one account initialize and write to the account. In practice, this is very restrictive. For example, if user Alice is transferring points to Bob, Alice must be able to write to an account initialized by user Bob. In this tutorial we […]

Deleting and Closing Accounts and Programs in Solana

Deleting and Closing Accounts and Programs in Solana In the Anchor framework for Solana, close is the opposite of init (initializing an account in Anchor) — it reduces the lamport balance to zero, sending the lamports to a target address, and changes the owner of the account to be the system program. Here is an […]

PDA (Program Derived Address) vs Keypair Account in Solana

PDA (Program Derived Address) vs Keypair Account in Solana A program derived address (PDA) is an account whose address is derived from the address of the program that created it and the seeds passed in to the init transaction. Up until this point, we’ve only used PDAs. It is also possible to create an account […]

Owner vs Authority in Solana

Owner vs Authority in Solana Newcomers to Solana are frequently confused by the distinction between an “owner” and an “authority.” This article attempts to clear up the confusion as succinctly as possible. Owner vs Authority Only programs can write data to accounts — specifically, only to accounts they own. A program cannot write data to […]

Multicall in Solana: Batching Transactions and Transaction Size Limit

Multicall in Solana: Batching Transactions and Transaction Size Limit Solana has multicall built in In Ethereum, we use the multicall pattern if we want to batch multiple transactions together atomically. If one fails, the rest fails. Solana has this built into the runtime, so we don’t need to implement a multicall. In the example below, […]

Init_if_needed in Anchor and the Reinitialization Attack

Init_if_needed in Anchor and the Reinitialization Attack In previous tutorials, we’ve had to initialize an account in a separate transaction before we can write data to it. We may wish to be able to initialize an account and write data to it in one transaction to simplify things for the user. Anchor provides a handy […]

Understanding Account Ownership in Solana: Transferring SOL out of a PDA

Understanding Account Ownership in Solana: Transferring SOL out of a PDA The owner of an account in Solana is able to reduce the SOL balance, write data to the account, and change the owner. Here is the summary of account ownership in Solana: The system program owns wallets and keypair accounts that haven’t been assigned […]

Transferring SOL and building a payment splitter: “msg.value” in Solana

Transferring SOL and building a payment splitter: “msg.value” in Solana This tutorial will introduce the mechanism by which Solana Anchor programs can transfer SOL as part of the transaction. Unlike Ethereum where wallets specify msg.value as part of the transaction and “push” the ETH to the contract, Solana programs “pull” the Solana from the wallet. […]

Function modifiers (view, pure, payable) and fallback functions in Solana: why they don’t exist

Function modifiers (view, pure, payable) and fallback functions in Solana: why they don’t exist Solana does not have fallback or receive functions A Solana transaction must specify in advance the accounts it will modify or read as part of a transaction. If a “fallback” function accesses an indeterminant account, then the entire transaction will fail. […]

Reading an account balance in Anchor: address(account).balance in Solana

Reading an account balance in Anchor: address(account).balance in Solana Reading an account balance in Anchor Rust To read the Solana balance of an address inside a Solana program, use the following code: use anchor_lang::prelude::*; declare_id!("Gnf6u7S7fGJbqEGH9PuDE5Prq6f6ZrDxHY3jNJ4SYySQ"); #[program] pub mod balance { use super::*; pub fn read_balance(ctx: Context<ReadBalance>) -> Result<()> { let balance = ctx.accounts.acct.to_account_info().lamports(); msg!("balance in […]

Cost of storage, maximum storage size, and account resizing in Solana

Cost of storage, maximum storage size, and account resizing in Solana When allocating storage space, the payer must pay a certain number of SOL per byte allocated. Solana calls this the “rent”. This name is a bit misleading because it implies a monthly top-up is required, but this is not always the case. Once the […]

Creating “mappings” and “nested mapping” in Solana

Creating “mappings” and “nested mapping” in Solana In the previous tutorials, the seeds=[] parameter was always empty. If we put data into it, it behaves like a key or keys in a Solidity mapping. Consider the following example: contract ExampleMapping { struct SomeNum { uint64 num; } mapping(uint64 => SomeNum) public exampleMap; function setExampleMap(uint64 key, […]

Read account data with Solana web3 js and Anchor

Read account data with Solana web3 js and Anchor This tutorial shows how to read account data directly from the Solana web3 Javascript client so that a web app could read it on the frontend. In the previous tutorial we used solana account <account address> to read the data we wrote, but this won’t work […]

Solana counter tutorial: reading and writing data to accounts

Solana counter tutorial: reading and writing data to accounts In our previous tutorial, we discussed how to initialize an account so that we could persist data in storage. This tutorial shows how to write to an account we have already initialized. Below is the code from the previous tutorial on initializing Solana accounts. We have […]

Initializing Accounts in Solana and Anchor

Initializing Accounts in Solana and Anchor Up until this point, none of our tutorials have used “storage variables” or stored anything permanent. In Solidity and Ethereum, a more exotic design pattern to store data is SSTORE2 or SSTORE3 where the data is stored in the bytecode of another smart contract. In Solana, this is not […]

Introduction to Solana Compute Units and Transaction Fees

Introduction to Solana Compute Units and Transaction Fees In Ethereum, the price of a transaction is computed as $\text{gasUsed} \times \text{gasPrice}$. This tells us how much Ether will be spent to include the transaction on the blockchain. Before a transaction is sent, a gasLimit is specified and paid upfront. If the transaction runs out of […]

Tx.origin, msg.sender, and onlyOwner in Solana: identifying the caller

Tx.origin, msg.sender, and onlyOwner in Solana: identifying the caller In Solidity, the msg.sender is a global variable that represents the address that called or initiated a function call on a smart contract. The global variable tx.origin is the wallet that signed the transaction. In Solana, there is no equivalent to msg.sender. There is an equivalent […]

Solana logs, “events,” and transaction history

Solana logs, “events,” and transaction history Solana programs can emit events similar to how Ethereum emits events, though there are some differences we will discuss. Specifically, events in Solana are intended to pass information to the frontend rather than document past transactions. To get past history, Solana transactions can be queried by address. Solana Logs […]

Solana Sysvars Explained

Solana Sysvars Explained In Solana, sysvars are read-only system accounts that give Solana programs access to the blockchain state as well as network information. They are similar to Ethereum global variables, which also enable smart contracts to access network or blockchain state information, but they have unique public addresses like the Ethereum precompiles. In Anchor […]

The Solana clock and other “block” variables

The Solana clock and other “block” variables Today we will cover the analogs of all the block variables from Solidity. Not all of them have 1-1 analogs. In Solidity, we have the following commonly used block variables: block.timestamp block.number blockhash() And the lesser known ones: block.coinbase block.basefee block.chainid block.difficulty / block.prevrandao We assume you already […]

Visibility and “inheritance” in Rust and Solana

Visibility and “inheritance” in Rust and Solana Today we will be learning how Solidity’s function visibility and contract inheritance can be conceptualized in Solana. There are four levels of function visibility in Solidity, they are: public – accessible from within the contract and externally. external – accessible from outside the contract only. internal – accessible […]

Rust Structs and Attribute-like and Custom Derive Macros

Rust Structs and Attribute-like and Custom Derive Macros Attribute-like and custom derive macros in Rust are used to take a block of Rust code and modify it in some way at compile time, often to add functionality. To understand attribute-like and custom derive macros in Rust, we first need to briefly cover implementation structs in […]

Rust function-like procedural Macros

Rust function-like procedural Macros This tutorial explains the distinction between functions and function like macros. For example, why does msg! have an exclamation point after it? This tutorial will explain this syntax. As a strongly typed language, Rust cannot accept an arbitrary number of arguments to a function. For example, the Python print function can […]

The unusual syntax of Rust

The unusual syntax of Rust Readers coming from a Solidity or Javascript background may find Rust’s usage and syntax of &, mut, <_>, unwrap(), and ? to be weird (or even ugly). This chapter explains what these terms mean. Don’t worry if everything doesn’t sink in right away. You can always come back to this […]

Basic Rust for Solidity Developers

Basic Rust for Solidity Developers This tutorial goes over the most commonly used syntax in Solidity and demonstrates the equivalent in Rust. If you want a high level overview of the differences of Rust vs Solidity please see the linked tutorial. This tutorial assumes you already know Solidity, so please see our free Solidity tutorial […]

Solana programs are upgradeable and do not have constructors

Solana programs are upgradeable and do not have constructors In this tutorial we will peek behind the scenes of anchor to see how a Solana program gets deployed. Let’s look at the test file anchor creates for us when we run anchor init deploy_tutorial: describe("deploy_tutorial", () => { // Configure the client to use the […]

Require, Revert, and Custom Errors in Solana

Require, Revert, and Custom Errors in Solana In Ethereum, we often see a require statement restricting the values a function argument can have. Consider the following example: function foobar(uint256 x) public { require(x < 100, "I'm not happy with the number you picked"); // rest of the function logic } In the code above, the […]

Solana Anchor Program IDL

Solana Anchor Program IDL The IDL (Interface Definition Language) is a JSON file that describes how to interact with a Solana program. It is automatically generated by the Anchor framework. There is nothing special about the function called “initialize” — it’s a name Anchor picks. What we will learn in this tutorial is how the […]

Arithmetic and Basic Types in Solana and Rust

Arithmetic and Basic Types in Solana and Rust Today we will learn how to create a Solana program that accomplishes the same things as the Solidity contract below. We will also learn how Solana handles arithmetic issues like overflow. contract Day2 { event Result(uint256); event Who(string, address); function doSomeMath(uint256 a, uint256 b) public { uint256 […]

Solana Hello World (Installation and Troubleshooting)

Solana Hello World (Installation and Troubleshooting) This is a Solana hello world tutorial. We will walk you through the steps to install Solana and troubleshoot issues that may arise. If you encounter an issue, please check the Troubleshooting section at the end of this article. Installation steps Install Rust Skip this if you already have […]

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 a smart contract, plus some additional useful features Foundry provides. Foundry has very extensive testing capabilities, so rather than rehashing the documentation, we will focus […]

Solana Smart Contract Programming Language

Solana Smart Contract Programming Language Solana programming language The primary Solana programming language is Rust, but C, C++, and even Python are supported. Solana coding language uses Rust, C, and C++ in a similar way. We’ll discuss Python in a later section. Rust is a compiled language. If you compile Rust on your computer, it […]