Writing Data to the Solana Blockchain

Solana Javascript SDK

@solana/web3.js is the JavaScript API built on top of the Solana JSON RPC API. We will use it to interact with the Solana Network

SDK Basics

Keypairs

Keypairs are a system of public and private keys used to access the Solana blockchain network. A keypair consists of a public key (which is publicly available and used to receive tokens) and a private key (which is kept securely and used to sign transactions).

Making a new KeyPair

const keypair = Keypair.generate()   // Helper function from **@solana/web3.js**
const publicKey = keypair.publickey  // Index public key
const privateKey = keypair.secretkey // Index private key

Transactions

Transactions are instructions that call solana programs, usually to modify on-chain data.

They have 3 key elements:

  • uid of the program to call

  • list of accounts to read/write to

  • data in the form of a byte array

/* a simple transaction might look like this. 
we are using helper functions from **@solana/web3.js** */

const transaction = new Transaction()

const sendInstruction = SystemProgram.transfer({
    fromPubkey: sender,                  // sender address
    toPubkey: recipient,                 // reciever address
    lamports: LAMPORTS_PER_SOL * amount  // amount of SOL to be sent
})

transaction.add(sendSolInstruction) 

Writing Data

Here is an example of a complete program that writes data to the network.

async function callProgram(
    connection: web3.Connection,
    payer: web3.Keypair,
    programId: web3.PublicKey,
    programDataAccount: web3.PublicKey
) {

    /* This is a new transaction instruction - the programId 
    is the key of the program you are calling and keys contains 
    accounts that will be written to */ 
    const instruction = new web3.TransactionInstruction({
        keys: [
            {
                pubkey: programDataAccount,
                isSigner: false,
                isWritable: true
            },
        ],
        programId
    })

    /* "sig" waits for the confirmation of the transaction being completed.
    The return of this is a signature created from the message and secret key, 
    used to log the transaction. */
    const sig = await web3.sendAndConfirmTransaction(
        connection,
        new web3.Transaction().add(instruction),
        [payer]
    )

    console.log(sig)
}

Assignment

  1. Generate a new keypair using the Keypair.generate() method from the @solana/web3.js library.

  2. Create a program that creates a new transaction that transfers a specified amount of SOL from the public key to another public key, while also storing a message to be sent with the transaction.

  3. The message should be encrypted using a basic encryption algorithm of the your choice (e.g. Caesar cipher, Vigenère cipher, etc.).

  4. Confirm that the transaction has been completed, retrieve the encrypted message from the data account, and decrypt it.

Note: You should use the information provided in the course, including the code examples, to complete the assignment. The program should be written in JavaScript and use the @solana/web3.js library.

Hint 1
Solution
import { Keypair } from '@solana/web3.js';
import { Connection, Transaction } from '@solana/web3.js/src/transaction';

// Step 1: Generate a new keypair
const keypair = Keypair.generate();
console.log('Private key: ', keypair.secretKey);
console.log('Public key: ', keypair.publicKey);

// Step 2: Create a new transaction
const transferAmount = 1000;
const recipientPublicKey = 'Public key of the recipient';
const message = 'This is a secret message';

// Basic encryption using Caesar cipher
function encrypt(text, shift) {
    let result = '';
    for (let i = 0; i < text.length; i++) {
        result += String.fromCharCode((text.charCodeAt(i) + shift - 65) % 26 + 65);
    }
    return result;
}

// Encrypt the message
const encryptedMessage = encrypt(message, 3);

// Create the transaction
const transaction = new Transaction();
transaction.addDataAccount(keypair.publicKey, encryptedMessage);
transaction.addTransfer(keypair.publicKey, recipientPublicKey, transferAmount);

// Step 3: Confirm the transaction has been completed
const connection = new Connection('<https://testnet.solana.com>');
const confirmation = await connection.sendRawTransaction(transaction.serialize(), keypair.secretKey);
console.log('Transaction confirmed: ', confirmation);

// Step 4: Retrieve the encrypted message and decrypt it
const dataAccount = await connection.getDataAccount(keypair.publicKey);
const decryptedMessage = encrypt(dataAccount.data, -3);
console.log('Decrypted message: ', decryptedMessage);

// Step 5 (Extra credit): Allow user input for message and encryption key
const readline = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
});

readline.question('Enter the message to be encrypted: ', (userMessage) => {
    readline.question('Enter the encryption key: ', (encryptionKey) => {
        const encrypted = encrypt(userMessage, parseInt(encryptionKey));
        console.log('Encrypted message: ', encrypted);
        readline.close();
    });
});

Once you’re done, make a PR with your react app to the homework repository on Github.

Last updated