How to Create a Solana Program Using Solidity and Solang

·

Overview

Solang is a Solidity compiler designed for Solana, enabling developers to write smart contracts in Solidity and deploy them on the Solana blockchain. With recent updates, Anchor (Solana's framework for building programs) now supports Solang. This guide walks you through creating and testing a Solana program using Solidity and Solang.

Key Objectives

Prerequisites

👉 QuickNode Solana Endpoints


Solang Basics

Solang compiles Solidity contracts for Solana, though it’s still under active development. Key differences from Ethereum’s Solidity stem from Solana’s architecture:

Accounts

Solana uses two account types:

  1. Programs: Executable code (stateless).
  2. Data Accounts: Store state (modifiable only by owning programs).

In Solang, the program ID is declared at the contract’s start:

@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")

Program Derived Addresses (PDAs)

PDAs are data stores owned by programs. Seeds (like a user’s public key) derive their addresses. Example in Solang:

@program_id("Foo5mMfYo5RhRcWa4NZ2bwFn4Kdhe8rNK5jchxsKrivA")
contract Foo {
    @space(500)
    @seed("Foo")
    @payer(payer)
    constructor(@seed bytes user_wallet, @bump bytes1 bump_val) {}
}

Interface Definition Language (IDL)

Similar to Ethereum’s ABI, IDLs define program-client interfaces. Anchor auto-generates IDLs during compilation.


Building a Scoreboard Program

Initialize the Project

  1. Create a new Anchor project:

    anchor init scoreboard --solidity
  2. Navigate to /solidity/scoreboard.sol and replace the template with:

    @program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")
    contract scoreboard {
        struct UserScore {
            address player;
            uint64 currentScore;
            uint64 highestScore;
            bytes1 bump;
        }
        UserScore private accountData;
    
        @payer(payer)
        @seed("seed")
        constructor(@seed bytes payer, @bump bytes1 bump, address player) {
            accountData = UserScore(player, 0, 0, bump);
        }
    }

Add Program Functions

  1. Setter Functions:

    function addPoints(uint8 numPoints) public {
        require(numPoints > 0 && numPoints <= 100, 'INVALID_POINTS');
        accountData.currentScore += numPoints;
        if (accountData.currentScore > accountData.highestScore) {
            accountData.highestScore = accountData.currentScore;
        }
    }
    
    function resetScore() public {
        accountData.currentScore = 0;
    }
  2. Getter Functions:

    function getCurrentScore() public view returns (uint64) {
        return accountData.currentScore;
    }

Compile and Deploy

Run:

anchor build
anchor deploy

Testing the Program

Test Cases

  1. Account Initialization:

    it("Initializes account", async () => {
        const tx = await program.methods.new(walletSeed, [bump], dataAccount)
            .accounts({ dataAccount })
            .rpc();
        const score = await program.methods.getCurrentScore()
            .accounts({ dataAccount })
            .view();
        assert.equal(score.toNumber(), 0);
    });
  2. Add Points:

    it("Adds points", async () => {
        await program.methods.addPoints(50)
            .accounts({ dataAccount })
            .rpc();
        const score = await program.methods.getCurrentScore()
            .accounts({ dataAccount })
            .view();
        assert.equal(score.toNumber(), 50);
    });

👉 Explore Solana PDAs


FAQ

1. Can I use Solang for production deployments?

Yes, but ensure thorough testing due to Solang’s evolving nature.

2. How do PDAs differ from Ethereum’s storage?

PDAs are owned by programs and require explicit initialization, unlike Ethereum’s automatic storage.

3. What’s the cost of deploying on Solana mainnet?

Small programs cost a few SOL in rent. Check your balance with solana balance.

4. How do I handle errors in Solang?

Use require() for conditions, similar to Solidity.

5. Can I interact with Solana programs using web3.js?

Yes, via the generated IDL and Anchor client libraries.


Conclusion

You’ve built a Solana program using Solidity and Solang! Key takeaways:

For further learning, check out:

🚀 Happy Building!