This repository has been archived by the owner on Jan 7, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 872
/
Copy pathhello_world.js
147 lines (131 loc) · 4.04 KB
/
hello_world.js
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// @flow
import {
Account,
Connection,
BpfLoader,
PublicKey,
SystemProgram,
TransactionInstruction,
Transaction,
} from '@solana/web3.js';
import fs from 'mz/fs';
import * as BufferLayout from 'buffer-layout';
import {url, urlTls} from '../../url';
import {Store} from './util/store';
import {newAccountWithLamports} from './util/new-account-with-lamports';
import {sendAndConfirmTransaction} from './util/send-and-confirm-transaction';
/**
* Connection to the network
*/
let connection: Connection;
/**
* Hello world's program id
*/
let programId: PublicKey;
/**
* The public key of the account we are saying hello to
*/
let greetedPubkey: PublicKey;
/**
* Layout of the greeted account data
*/
const greetedAccountDataLayout = BufferLayout.struct([
BufferLayout.u32('numGreets'),
]);
/**
* Establish a connection to the cluster
*/
export async function establishConnection(): Promise<void> {
connection = new Connection(url, 'recent');
const version = await connection.getVersion();
console.log('Connection to cluster established:', url, version);
}
/**
* Load the hello world BPF program if not already loaded
*/
export async function loadProgram(): Promise<void> {
const store = new Store();
// Check if the program has already been loaded
try {
let config = await store.load('config.json');
programId = new PublicKey(config.programId);
greetedPubkey = new PublicKey(config.greetedPubkey);
await connection.getAccountInfo(programId);
console.log('Program already loaded to account', programId.toBase58());
return;
} catch (err) {
// try to load the program
}
// Read the BPF program bytes
const data = await fs.readFile(
'src/program/target/bpfel-unknown-unknown/release/solana_bpf_helloworld.so',
);
// Calculate the cost to load the program
const {feeCalculator} = await connection.getRecentBlockhash();
const NUM_RETRIES = 500; // allow some number of retries
let cost =
feeCalculator.lamportsPerSignature *
(BpfLoader.getMinNumSignatures(data.length) + NUM_RETRIES) +
(await connection.getMinimumBalanceForRentExemption(data.length));
const bpf_payer = await newAccountWithLamports(connection, cost);
// Load the program
console.log('Loading hello world program...');
programId = await BpfLoader.load(connection, bpf_payer, data);
console.log('Program loaded to account', programId.toBase58());
// Create the greeted account
const greetedAccount = new Account();
greetedPubkey = greetedAccount.publicKey;
console.log('Creating account', greetedPubkey.toBase58(), 'to say hello to');
const space = 4; // 64-bit number
const lamports = await connection.getMinimumBalanceForRentExemption(space);
const payer = await newAccountWithLamports(connection, lamports);
const transaction = SystemProgram.createAccount({
fromPubkey: payer.publicKey,
newAccountPubkey: greetedPubkey,
lamports,
space,
programId,
});
await sendAndConfirmTransaction(
'createAccount',
connection,
transaction,
payer,
greetedAccount,
);
// Save this info for next time
await store.save('config.json', {
url: urlTls,
programId: programId.toBase58(),
greetedPubkey: greetedPubkey.toBase58(),
});
}
/**
* Say hello
*/
export async function sayHello(): Promise<void> {
console.log('Saying hello to', greetedPubkey.toBase58());
const instruction = new TransactionInstruction({
keys: [{pubkey: greetedPubkey, isSigner: false, isWritable: true}],
programId,
data: Buffer.alloc(0), // All instructions are hellos
});
await sendAndConfirmTransaction(
'sayHello',
connection,
new Transaction().add(instruction),
);
}
/**
* Report the number of times the greeted account has been said hello to
*/
export async function reportHellos(): Promise<void> {
const accountInfo = await connection.getAccountInfo(greetedPubkey);
const info = greetedAccountDataLayout.decode(Buffer.from(accountInfo.data));
console.log(
greetedPubkey.toBase58(),
'has been greeted',
info.numGreets.toString(),
'times',
);
}