Skip to content

Commit 0c8e9bb

Browse files
authored
Merge pull request solana-developers#35 from ZYJLiu/main
Add Solang Program Examples
2 parents ed2a00c + edab522 commit 0c8e9bb

File tree

114 files changed

+7996
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+7996
-0
lines changed

basics/account-data/solang/.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
.anchor
3+
.DS_Store
4+
target
5+
**/*.rs.bk
6+
node_modules
7+
test-ledger
8+
.yarn
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[features]
2+
seeds = false
3+
skip-lint = false
4+
[programs.localnet]
5+
account_data = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC"
6+
7+
[registry]
8+
url = "https://api.apr.dev"
9+
10+
[provider]
11+
cluster = "Localnet"
12+
wallet = "~/.config/solana/id.json"
13+
14+
[scripts]
15+
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"scripts": {
3+
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
4+
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
5+
},
6+
"dependencies": {
7+
"@coral-xyz/anchor": "^0.28.0"
8+
},
9+
"devDependencies": {
10+
"chai": "^4.3.4",
11+
"mocha": "^9.0.3",
12+
"ts-mocha": "^10.0.0",
13+
"@types/bn.js": "^5.1.0",
14+
"@types/chai": "^4.3.0",
15+
"@types/mocha": "^9.0.0",
16+
"typescript": "^4.3.5",
17+
"prettier": "^2.6.2"
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")
3+
contract account_data {
4+
// A private instance of the AddressInfo struct
5+
// This is the data that is stored in the account
6+
AddressInfo private addressInfo;
7+
8+
// The AddressInfo struct definition
9+
struct AddressInfo {
10+
string name;
11+
uint8 houseNumber;
12+
string street;
13+
string city;
14+
}
15+
16+
@payer(payer) // "payer" is the account that pays to create the dataAccount
17+
@space(space) // "space" allocated to the account (maximum 10240 bytes, maximum space that can be reallocate when creating account in program via a CPI)
18+
constructor(address payer, uint16 space, string _name, uint8 _houseNumber, string _street, string _city) {
19+
// The AddressInfo instance is initialized with the data passed to the constructor
20+
addressInfo = AddressInfo(_name, _houseNumber, _street, _city);
21+
}
22+
23+
// A function to get the addressInfo data stored on the account
24+
function get() public view returns (AddressInfo) {
25+
return addressInfo;
26+
}
27+
28+
// A function to get the size in bytes of the stored AddressInfo
29+
function getAddressInfoSize() public view returns(uint) {
30+
uint size = 0;
31+
size += bytes(addressInfo.name).length;
32+
size += 1; // For houseNumber, which is uint8 and takes 1 byte
33+
size += bytes(addressInfo.street).length;
34+
size += bytes(addressInfo.city).length;
35+
return size;
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import * as anchor from "@coral-xyz/anchor"
2+
import { Program } from "@coral-xyz/anchor"
3+
import { AccountData } from "../target/types/account_data"
4+
5+
describe("account-data", () => {
6+
// Configure the client to use the local cluster.
7+
const provider = anchor.AnchorProvider.env()
8+
anchor.setProvider(provider)
9+
10+
// Generate a new random keypair for the data account.
11+
const dataAccount = anchor.web3.Keypair.generate()
12+
const wallet = provider.wallet
13+
const program = anchor.workspace.AccountData as Program<AccountData>
14+
15+
// Create the new account
16+
// Using 10240 bytes of space, because its unclear how to correctly calculate the minimum space needed for the account
17+
// Space calculation is different from regular Native/Anchor Solana programs
18+
it("Is initialized!", async () => {
19+
const tx = await program.methods
20+
.new(
21+
wallet.publicKey, // payer
22+
10240, // space (10240 bytes is the maximum space allowed when allocating space through a program)
23+
"Joe C", // name
24+
136, // house number
25+
"Mile High Dr.", // street
26+
"Solana Beach" // city
27+
)
28+
.accounts({ dataAccount: dataAccount.publicKey })
29+
.signers([dataAccount])
30+
.rpc()
31+
console.log("Your transaction signature", tx)
32+
})
33+
34+
// Get the account data
35+
it("Get AddressInfo Data", async () => {
36+
const val = await program.methods
37+
.get()
38+
.accounts({ dataAccount: dataAccount.publicKey })
39+
.view()
40+
console.log("State:", val)
41+
})
42+
43+
// Get the account data size
44+
// Testing how much space is used to store the account data
45+
// However, minimum space required is greater than this
46+
it("Get AddressInfo Size", async () => {
47+
const size = await program.methods
48+
.getAddressInfoSize()
49+
.accounts({ dataAccount: dataAccount.publicKey })
50+
.view()
51+
console.log("Size:", size.toNumber())
52+
})
53+
})
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"compilerOptions": {
3+
"types": ["mocha", "chai"],
4+
"typeRoots": ["./node_modules/@types"],
5+
"lib": ["es2015"],
6+
"module": "commonjs",
7+
"target": "es6",
8+
"esModuleInterop": true
9+
}
10+
}
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
.anchor
3+
.DS_Store
4+
target
5+
**/*.rs.bk
6+
node_modules
7+
test-ledger
8+
.yarn
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[features]
2+
seeds = false
3+
skip-lint = false
4+
[programs.localnet]
5+
checking_accounts = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC"
6+
7+
[registry]
8+
url = "https://api.apr.dev"
9+
10+
[provider]
11+
cluster = "Localnet"
12+
wallet = "~/.config/solana/id.json"
13+
14+
[scripts]
15+
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"scripts": {
3+
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
4+
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
5+
},
6+
"dependencies": {
7+
"@coral-xyz/anchor": "^0.28.0"
8+
},
9+
"devDependencies": {
10+
"chai": "^4.3.4",
11+
"mocha": "^9.0.3",
12+
"ts-mocha": "^10.0.0",
13+
"@types/bn.js": "^5.1.0",
14+
"@types/chai": "^4.3.0",
15+
"@types/mocha": "^9.0.0",
16+
"typescript": "^4.3.5",
17+
"prettier": "^2.6.2"
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
2+
import "solana";
3+
4+
@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")
5+
contract checking_accounts {
6+
7+
// The dataAccount is unused in this example, but is a required account when using Solang
8+
@payer(payer) // "payer" is the account that pays to create the dataAccount
9+
constructor(address payer) {}
10+
11+
function checkAccounts(address accountToChange, address accountToCreate) public view {
12+
print("Number of Accounts Provided: {:}".format(tx.accounts.length));
13+
14+
// Find the accounts we are looking for and perform checks on them
15+
for (uint64 i = 0; i < tx.accounts.length; i++) {
16+
if (tx.accounts[i].key == accountToChange) {
17+
print("Found Account To Change");
18+
programOwnerCheck(tx.accounts[i]);
19+
}
20+
if (tx.accounts[i].key == accountToCreate) {
21+
print("Found Account To Create");
22+
notInitializedCheck(tx.accounts[i]);
23+
signerCheck(tx.accounts[i]);
24+
}
25+
}
26+
27+
// (Create account...) (unimplemented)
28+
// (Change account...) (unimplemented)
29+
}
30+
31+
function programOwnerCheck(AccountInfo account) internal pure {
32+
print("Progam Owner Check");
33+
// The owner of this account should be this program
34+
require(account.owner == type(checking_accounts).program_id, "Account to change does not have the correct program id.");
35+
}
36+
37+
function notInitializedCheck(AccountInfo account) internal pure {
38+
print("Check Account Not Initialized");
39+
// This account should not be initialized (has no lamports)
40+
require(account.lamports == 0, "The program expected the account to create to not yet be initialized.");
41+
}
42+
43+
function signerCheck(AccountInfo account) internal pure {
44+
print("Check Account Signed Transaction");
45+
// This account should be a signer on the transaction
46+
require(account.is_signer, "Account required to be a signer");
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import * as anchor from "@coral-xyz/anchor"
2+
import { Program } from "@coral-xyz/anchor"
3+
import { CheckingAccounts } from "../target/types/checking_accounts"
4+
import {
5+
SystemProgram,
6+
Transaction,
7+
sendAndConfirmTransaction,
8+
} from "@solana/web3.js"
9+
10+
describe("checking-accounts", () => {
11+
// Configure the client to use the local cluster.
12+
const provider = anchor.AnchorProvider.env()
13+
anchor.setProvider(provider)
14+
15+
// Generate a new random keypair for the data account.
16+
const dataAccount = anchor.web3.Keypair.generate()
17+
18+
// Generate a new keypair to represent the account we will change.
19+
const accountToChange = anchor.web3.Keypair.generate()
20+
// Generate a new keypair to represent the account we will create.
21+
const accountToCreate = anchor.web3.Keypair.generate()
22+
const wallet = provider.wallet as anchor.Wallet
23+
const connection = provider.connection
24+
25+
const program = anchor.workspace.CheckingAccounts as Program<CheckingAccounts>
26+
27+
it("Is initialized!", async () => {
28+
// Create the new dataAccount, this is an account required by Solang even though we don't use it
29+
const tx = await program.methods
30+
.new(wallet.publicKey)
31+
.accounts({ dataAccount: dataAccount.publicKey })
32+
.signers([dataAccount])
33+
.rpc({ skipPreflight: true })
34+
console.log("Your transaction signature", tx)
35+
})
36+
37+
it("Create an account owned by our program", async () => {
38+
// Create the new account owned by our program by directly calling the system program
39+
let ix = SystemProgram.createAccount({
40+
fromPubkey: wallet.publicKey,
41+
newAccountPubkey: accountToChange.publicKey,
42+
lamports: await connection.getMinimumBalanceForRentExemption(0),
43+
space: 0,
44+
programId: program.programId, // Our program
45+
})
46+
47+
await sendAndConfirmTransaction(connection, new Transaction().add(ix), [
48+
wallet.payer,
49+
accountToChange,
50+
])
51+
})
52+
53+
it("Check Accounts", async () => {
54+
// Invoke the checkAccounts instruction on our program, passing in the account we want to "check"
55+
const tx = await program.methods
56+
.checkAccounts(accountToChange.publicKey, accountToCreate.publicKey)
57+
.accounts({ dataAccount: dataAccount.publicKey })
58+
.remainingAccounts([
59+
{
60+
pubkey: accountToChange.publicKey,
61+
isWritable: true,
62+
isSigner: false,
63+
},
64+
{
65+
pubkey: accountToCreate.publicKey,
66+
isWritable: true,
67+
isSigner: true,
68+
},
69+
])
70+
.signers([accountToCreate])
71+
.rpc({ skipPreflight: true })
72+
console.log("Your transaction signature", tx)
73+
})
74+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"compilerOptions": {
3+
"types": ["mocha", "chai"],
4+
"typeRoots": ["./node_modules/@types"],
5+
"lib": ["es2015"],
6+
"module": "commonjs",
7+
"target": "es6",
8+
"esModuleInterop": true
9+
}
10+
}
11+

basics/counter/solang/.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
.anchor
3+
.DS_Store
4+
target
5+
**/*.rs.bk
6+
node_modules
7+
test-ledger
8+
.yarn

basics/counter/solang/Anchor.toml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[features]
2+
seeds = false
3+
skip-lint = false
4+
[programs.localnet]
5+
counter = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC"
6+
7+
[registry]
8+
url = "https://api.apr.dev"
9+
10+
[provider]
11+
cluster = "Localnet"
12+
wallet = "~/.config/solana/id.json"
13+
14+
[scripts]
15+
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

basics/counter/solang/package.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"scripts": {
3+
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
4+
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
5+
},
6+
"dependencies": {
7+
"@coral-xyz/anchor": "^0.28.0"
8+
},
9+
"devDependencies": {
10+
"chai": "^4.3.4",
11+
"mocha": "^9.0.3",
12+
"ts-mocha": "^10.0.0",
13+
"@types/bn.js": "^5.1.0",
14+
"@types/chai": "^4.3.0",
15+
"@types/mocha": "^9.0.0",
16+
"typescript": "^4.3.5",
17+
"prettier": "^2.6.2"
18+
}
19+
}

0 commit comments

Comments
 (0)