Better Programming

Advice for programmers.

Follow publication

Getting Started With Solana for Solidity Developers

Start your Solana journey by comparing programming models of Ethereum vs Solana

Nazar Ilamanov
Better Programming
Published in
8 min readApr 12, 2022

If you’re familiar with Ethereum and Solidity, you might be meaning to dip your toes into the Solana ecosystem. Solana’s fast blockchain is promising and exciting. Plus you increase the surface area of your web3 knowledge.

But if you’ve never seen a Solana program, its syntax is freaking scary and the docs seem like one dev’s repurposed notes. There is no coherence and you won’t understand some parts until later sections.

This is why I created this “Solana Ramp for Solidity Devs” series for introducing you gently and without pain and frustration to Solana. The first article in this series (this one) is the “Programming model comparison of Ethereum vs Solana” which is essentially just conceptual differences in how you write a program in ETH vs SOL.

We won’t go into how Solana works behind the scenes like its proof of history, etc. This is going to be in another article.

Here is the outline of this article:

  • Storing state in Ethereum vs Solana
  • Solana accounts
  • Program Derived Addresses

Storing state in Ethereum vs Solana

In Ethereum, you’re used to storing state right in the smart contract itself. Take a look at this simple contract:

It just stores one variable author and has a helper publish function which mutates the author variable. You deploy this contract and the code along with its state is stored at one address. You can use that address to refer to the contract and read its data (on Etherscan for example).

But Solana is different.

Solana contracts are stateless. Think of them as just instructions. They don’t store any data/state. Where is the data stored then? It’s stored in separate “accounts”. Accounts hold the data. When you call a Solana contract’s function, you need to pass in the data to the function.

So the publish function above would require a reference to the account that stores the data. The function would increment the number of publications, but the author variable would still be stored in the same account (not in the contract). The state of the contract did not change. If you’re from the Java world, a Solana contract is like a static class in Java.

BTW, smart contracts are called programs in Solana.

Here is what the simple contract above would look like in Solana:

Notice how the data is stored in a separate AuthorAccount and this data is passed in by reference to the publish function (via Context). The solana_example program does not store anything by itself. It just operates on the passed-in data. (AuthorData is kinda like a wrapper needed to pass in the AuthorAccount to the publish function).

The syntax is freaking scary, I know. This is Rust and Anchor (Solana framework). It reminds me of the days I started iOS development and encountered Objective C for the first time. Don’t worry, we will look at the syntax in more detail in the second article of this series. It will make more sense, I promise.

Separating the code from data makes it easy to upgrade programs. In Solana, it’s possible to redeploy a new version of a program to the same address while reusing the same data account — an upgrade without loss of data. (This is much harder to do in Ethereum).

Solana accounts

“Account” is an ambiguous word. It means lots of things in different contexts. In Solana, an account just means a storage unit. It’s just a container to store arbitrary data.

There are 2 types of accounts. First is a “data account” which just stores data for programs like the AuthorAccount that we already mentioned. The second type is a “program account” and is used for “hosting” the code of programs. When you deploy a program on Solana, its code is stored in a “program account”.

An example: if you have a counter program that lets you increment a counter, you must create two accounts: one account to store the program’s code, and one to store the counter value.

Accounts have public keys/addresses in order to be able to reference them and they have private keys which are used in signatures to prove authority to modify accounts

The word “authority” is used quite a lot in Solana world. It just means the owner — the holder of private keys.

Accounts also store balances. Solana balances. Solana's native currency unit is SOL and Lamport (named in honor of Solana’s biggest technical influence, Leslie Lamport). 1 SOL = 10⁹ Lamports. These are analogs of ETH and wei.

In order to create an account, Solana needs to allocate space on its storage. Storage on Solana is not free, so creating an account is not free. You need to pay rent to Solana for “hosting” your account. But don’t worry. If you deposit 2 years' worth of rent to your account, you will be exempt from rent. Everyone just does that so storage essentially becomes free on Solana.

Here is a summary of everything stored in a Solana account:

From Solana wiki

data field either stores the code or arbitrary data depending on whether the account is executable. We will talk about the owner field in a bit.

Ethereum also has 2 types of accounts:

  • externally owned — regular accounts that can be generated by your wallet (just need to generate a private key, then derive the public key and address, and you have an account). These accounts simply store the balance and nonce.
  • Smart contract account — these store EVM code and also has a storage map that can be used for storing arbitrary data.

Here is what’s stored in the Ethereum account, for comparison:

From Solana wiki

codeHash is for storing the code and storageRoot is for storing arbitrary data. For non-executable accounts, the storageRoot is set to a special “null” hash which indicates the account has no storage.

In Ethereum, only “executable accounts” have storage. But in Solana, all accounts can store data. However, executable account data is used exclusively for immutable byte code. All other data is stored in non-executable accounts which are owned by the executable account.

Now, let’s talk about the owner field of Solana accounts.

To ensure that contracts can’t modify another contract’s state, each data account assigns an owner program that has exclusive control over state mutations. By default, the owner program is Solana’s system program (kinda like an Operating System).

No one other than the owner can modify the state of the data account. Anyone can deposit money to an account but only the owner can withdraw the balance.

At this point, you know-how programs and accounts work on Solana. But there is a little awkwardness in Solana that is not present in Ethereum.

Imagine you deployed a program to Solana and you also deployed a traditional web2 frontend to AWS for interacting with the program. Every time you call the program, you need to pass in the data account (to modify state). You need to own the private keys of the data account in order to be able to change the state of the data account.

The managing of the keys falls on you. Where are you going to store it? in web2 servers as environment variables? This is not very web3. It would be nice to store this key in the program itself to make it more like Ethereum — a way to attach storage to the program.

Program Derived Addresses (PDAs) solve this.

Program Derived Addresses (PDAs)

PDAs essentially allow you to attach a data storage account to a stateless program account. A way to make Solana Ethereum-like.

How does it work? In the program, you just generate an address from the variables controlled by the program. This becomes a derived account (a program-derived address). The Solana OS provides a helper function to derive this address.

More specifically, PDAs are derived from a program ID and a collection of seeds. The program ID is the address of the Solana program. The seeds can be chosen arbitrarily by the program (we will see where seeds become useful).

The process is deterministic: the combination of seeds and a program ID is run through a sha256 hash function to see whether or not they generate a public key that lies on the elliptic curve (there is a ~50% that the resulting public key will lie on the elliptic curve). If it does lie on the elliptic curve, we simply add something to fudge our input a little bit and try again. The technical term for this fudge factor is a bump . In Solana, we start with bump = 255 and simply iterate down through bump = 254 , bump = 253 , etc. until we get an address that is not on the elliptic curve

What does “lie on the elliptic curve mean”? When a public key lies on the elliptic curve, it means that there exists a corresponding private key that will make the whole private-key-cryptography algorithms work.

There’s a function called findProgramDerivedAddress that abstracts away the entire process.

Phew, that was a lot of technical stuff. If I lost you there, essentially PDA is generated from the program ID and some seeds such that the resulting address does not have a corresponding private key. Now, how is this PDA useful for attaching storage to Solana programs?

PDAs solve a few things:

  • No need to manage/keep track of private keys for the storage account. Just derive an address from the program and use that address/account as storage. How do you make sure that someone else does not modify the derived account? Because there is no corresponding private key of the derived address. So no one can modify this account. Solana OS makes sure only the programs are allowed to modify PDAs. How do you make sure that other programs can’t derive the same PDA? They can’t because their program ID will be different.
  • PDAs can also be used to store user-specific info in separate accounts. This is where seeds become useful. A common practice is to generate PDAs using the public key of an end-user as the seed, allowing our program to store information about that user in its own standalone account. Programs can deterministically derive any number of addresses by using different seeds. These seeds can symbolically identify how the addresses are used. For example, you can use the user’s public key and a token’s symbol as the seeds and get an account for storing the user’s information about a particular token (there will be a new PDA account for each user and for each token).

To summarize, a PDA is just an account whose owner is a program and does not have a private key like other accounts. Since there is no associated private key, an external user cannot generate a valid signature for the PDA. Only the program whose seeds result in the PDA can control it — this is enforced by Solana OS.

That’s it for the “differences in programming models of Solana vs Ethereum”. You can check the whole “Solana Ramp for Solidity Devs” series and more stuff for Solidity noobs on SolidNoob.

I am planning to do more Solana intro articles like “syntax difference” and “difference in ERC-721/ERC20 implementation”.

Want to Connect?Follow me on Twitter.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response