Accounts [Solana]

  • send new tx(when u write to blockchain)

    1. find the current node leader
    2. make sure that state is propagated on comming blocks as well.

Accounts

  • programs in solana are smartcontract equivalent of eth.

  • programs are stateless. i.e they don’t store any state.

  • programs only store code.

  • so state is maintained in Account.

3 types of accounts

  1. data account
  2. program accounts (store executable programs)
  3. native accounts(for core blockchain functionality like - staking, governance)

Data Account:

  • two types
  1. System owned accounts:
  2. PDA (program drived adderes) accounts:

every account has these attributes you should be aware of :

  • lamports(how many lamports(smallest unit of solana i.e 0.000000001 SOL) this account has.),

  • owner(owner of this account, expressed in PublicKey),

  • executable(a flag indecating if a this account is executable. i.e can it handle executable instructions or not),

  • rent_epoch(the upcomming time indicating when this account should pay rent.)

Reading stuff from solana

  • you just make request to RPC, which then talks to Solana network.

Why do we need libaries like web3 solana?

  • helps minize bolilerplate
  • without web3 trying to read account balance would be sth like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
async function getBalanceUsingJSONRPC(address: string): Promise<number> {
const url = clusterApiUrl('devnet')
console.log(url);
return fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"jsonrpc": "2.0",
"id": 1,
"method": "getBalance",
"params": [
address
]
})
}).then(response => response.json())
.then(json => {
if (json.error) {
throw json.error
}

return json['result']['value'] as number;
})
.catch(error => {
throw error
})
}

  • with web3 solana library we can minimize the abouve code like this:
1
2
3
4
async function getBalanceUsingWeb3(address: PublicKey): Promise<number> {
const connection = new Connection(clusterApiUrl('devnet'));
return connection.getBalance(address);
}

Writing in Solana

  • inorder to write, cerntain conditions need to be met else it will be discarded

  • Keypairs: one is public, the other is private/secrete

  • we have 3 ways in which secrets(private keys) can be:

  1. mnemonic phrase (pill tomorrow foster begin walnut borrow virtual kick shift mutual shoe scatter)
  2. base58 strings (for example phatonm generates this when u want to export your private key)
  3. byte array (u will usually use this in when coding)

When working on mainnet, it’s bad idea to store secrets inside .env file. You better find some tools that manage keys(i.e encrpt them and provide the keys to application at run time.https://security.stackexchange.com/questions/197784/is-it-unsafe-to-use-environmental-variables-for-secret-data?utm_source=buildspace.so&utm_medium=buildspace_project)

Transactions(i.e writing in solana)

  • tell programs to execute some instructions and if they’re accepted it will go through. i.e the effect is changes the state of blockchain. That’s why they need to be valid.

  • transactions contain these

    • array of programs they’re going to interact with.
    • Account in which, they’re reading/writing data to.
    • Byte array of data, that is going to be used by the program.

make and send a transaction

  • let’s see how we can easily send SOL in solana, using web3.js
  • like mentioned above transaction gonna have these: Accounts(read/write data to), data as byte array and off course the Program it’s going to invoke.
1
2
3
4
5
6
7
const transaction = new Transaction()
const sendSolInstruction = SystemProgram.transfer({
from:sender_public_key,
to: reciever_public_key
lamports: 1 * LAMPORT_PER_SOL
})
transcation.add(sendSolInstruction)
  • so, we can see it is interacting with a program called (SystemProgram), the data could be the ammount of SOL we’re writing to, and internally, solana knows which Account state to update when sending a transaction.

  • we can add multiple instructions to a transaction and they will be executed in order they’re inserted.

  • so, the above is just a transaction with its instruction, we need send that transaction. web3.js has go us covered with the function to do that.

1
2
3
4
5
sendAndConfirmTransaction({
connection, // the network(i.e devnet/mainnet)
transaction, // the transaction
[signers] // the signers array so solana runtime can know who authorized the transction.
});

Instructions in bit more detail

  • the above instruction looks pretty simple, thanks to web3.js for handling sendSol instruction.

  • but in a bit more detail, instructions look something like this:

  • keys of type array of AccountMeta: the accounts involved in the trasaction with more details. The more details are if the account is signer or not, is writiable i.e during the trasction is data gonna be written to this specific account, public key of the account.

  • programId of type public key: the need to know what program we’re talking to.

  • data of type Buffer: this is optional

1
2
3
4
5
6
7
8
9
10
11
const customInstruction = new TransactionInstruction({
keys: [{
pubKey: publicKey,
isWritable: true/false,
isSigner: true/false,
}],
programId: public_key_of_program_we_gonna_talk_to,
data?: optional_field
})

sendAndConfirmTransaction(connection, new Transaction().add(customInstruction), [payer_of_this_transaction_i.e_sender_or_signer_of_the_transaction] )

Transaction fees

  • when sending transaction someone is providing space and processing power. so, tx fees incentivize people like this.

  • NOTE: first signer in signers array is the one whose gonna pay the transaction fee.

  • use can use solana airdrop (from CLI) or faucet in browser to get some fake SOL