Created
April 23, 2022 03:20
-
-
Save keitaj/c6bce4dbd7f4f23bbadfc339e45691ca to your computer and use it in GitHub Desktop.
Solana Program Tutorial
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use borsh::{BorshDeserialize, BorshSerialize}; | |
use solana_program::{ | |
account_info::{next_account_info, AccountInfo}, | |
entrypoint, | |
entrypoint::ProgramResult, | |
msg, | |
program_error::ProgramError, | |
pubkey::Pubkey, | |
}; | |
/// Define the type of state stored in accounts | |
#[derive(BorshSerialize, BorshDeserialize, Debug)] | |
pub struct GreetingAccount { | |
/// number of greetings | |
pub counter: u32, | |
} | |
// Declare and export the program's entrypoint | |
entrypoint!(process_instruction); | |
// Program entrypoint's implementation | |
pub fn process_instruction( | |
program_id: &Pubkey, // Public key of the account the hello world program was loaded into | |
accounts: &[AccountInfo], // The account to say hello to | |
_instruction_data: &[u8], // Ignored, all helloworld instructions are hellos | |
) -> ProgramResult { | |
msg!("Hello World Rust program entrypoint"); | |
// Iterating accounts is safer than indexing | |
let accounts_iter = &mut accounts.iter(); | |
// Get the account to say hello to | |
let account = next_account_info(accounts_iter)?; | |
// The account must be owned by the program in order to modify its data | |
if account.owner != program_id { | |
msg!("Greeted account does not have the correct program id"); | |
return Err(ProgramError::IncorrectProgramId); | |
} | |
// Increment and store the number of times the account has been greeted | |
let mut greeting_account = GreetingAccount::try_from_slice(&account.data.borrow())?; | |
greeting_account.counter += 1; | |
greeting_account.serialize(&mut &mut account.data.borrow_mut()[..])?; | |
msg!("Greeted {} time(s)!", greeting_account.counter); | |
Ok(()) | |
} | |
// Sanity tests | |
#[cfg(test)] | |
mod test { | |
use super::*; | |
use solana_program::clock::Epoch; | |
use std::mem; | |
#[test] | |
fn test_sanity() { | |
let program_id = Pubkey::default(); | |
let key = Pubkey::default(); | |
let mut lamports = 0; | |
let mut data = vec![0; mem::size_of::<u32>()]; | |
let owner = Pubkey::default(); | |
let account = AccountInfo::new( | |
&key, | |
false, | |
true, | |
&mut lamports, | |
&mut data, | |
&owner, | |
false, | |
Epoch::default(), | |
); | |
let instruction_data: Vec<u8> = Vec::new(); | |
let accounts = vec![account]; | |
assert_eq!( | |
GreetingAccount::try_from_slice(&accounts[0].data.borrow()) | |
.unwrap() | |
.counter, | |
0 | |
); | |
process_instruction(&program_id, &accounts, &instruction_data).unwrap(); | |
assert_eq!( | |
GreetingAccount::try_from_slice(&accounts[0].data.borrow()) | |
.unwrap() | |
.counter, | |
1 | |
); | |
process_instruction(&program_id, &accounts, &instruction_data).unwrap(); | |
assert_eq!( | |
GreetingAccount::try_from_slice(&accounts[0].data.borrow()) | |
.unwrap() | |
.counter, | |
2 | |
); | |
} | |
} |
Deploy a Solana program
これからデプロイするプログラムは、あるアカウントが挨拶の指示を送った回数を記録しています。これは、Solana上でストレージがどのように機能するかを効果的に示すものです。
Building the program
yarn run solana:build:program
成功すると、helloworld.soというコンパイル済みのプログラムへのパスを指定してdeployコマンドを実行するように指示されます。このままでもいいのですが、この目的のためだけに生成したキーペアを指定したいので、読み進めてください。
To deploy this program:
$ solana program deploy /home/zu/project/figment/learn-web3-dapp/dist/solana/program/helloworld.so
Done in 1.39s.
Deploying the program
CLIのsolana deployを使って、プログラムをdevnetクラスタにデプロイする
solana deploy -v --keypair solana-wallet/keypair.json dist/solana/program/helloworld.so
vフラグはオプションですが、RPC URLやデフォルトの署名者鍵ペアのパス、予想されるコミットメントレベルなどの関連情報が表示されます。プロセスが完了すると、プログラムIDが表示されます。
成功した場合、CLIはデプロイされたコントラクトのprogramIdを表示します。
RPC URL: https://api.devnet.solana.com
Default Signer Path: solana-wallet/keypair.json
Commitment: confirmed
Program Id: 8LwWMLn37RKFLFz84HwaigLfpeoXCaXSFhcXooeDQBpW
Deploying the program to a test validator inside Gitpod
クラスタの変更
solana config set --url http://127.0.0.1:8899
テストバリデーターの実行
solana-test-validator
Gitpodで新しいターミナルを開きます (あるいはテストバリデータを実行しているターミナルを分割します)。この新しいターミナルで、Solana CLI の場所をコマンドで PATH に追加する必要があります。
export PATH="/home/gitpod/.local/share/solana/install/active_release/bin:$PATH"
/solana-wallet/keypair.json にあるキーペアに SOL の残高があることを確認し、SOL をいくらかエアドロップすることでデプロイの代金を支払います (テストバリデータ上なので、もっと高額な SOL を指定することも可能です)。
solana airdrop 100 $(solana-keygen pubkey solana-wallet/keypair.json)
これで、プログラムをテストバリデータにデプロイするコマンドを実行することができます。
solana deploy -v --keypair solana-wallet/keypair.json dist/solana/program/helloworld.so
Refs
% solana --version
solana-cli 1.10.5 (src:5eb085fc; feat:3235626988)
% rustc --version
rustc 1.60.0 (7737e0b5c 2022-04-04)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Solana programデプロイする前にRustのインストールが必要
https://doc.rust-jp.rs/book-ja/ch01-01-installation.html
Filesize limit exceededのエラー出たらとりあえずこれで対応
インストールしたらPATH通す
rustを最新版にアップデート
rustcのバージョン確認