Browse Source

rent native

jpcaulfi 3 years ago
parent
commit
51119b112a

+ 1 - 1
README.md

@@ -51,7 +51,7 @@ Regardless of what you may want to add on top of existing Solana programs, the n
 - [x] 3. Recommended program layout
 - ### [ ] Accounts
 - [x] 1. Creating a system account
-- [ ] 2. Rent
+- [x] 2. Rent
 - [x] 3. Transferring SOL
 - [ ] 4. Transferring an account's ownership
 - [ ] 5. Destroying an account

+ 1 - 1
accounts/rent/anchor/Anchor.toml

@@ -1,7 +1,7 @@
 [features]
 seeds = false
 [programs.localnet]
-create_system_account = "6gUwvaZPvC8ZxKuC1h5aKz4mRd7pFyEfUZckiEsBZSbk"
+rent_example = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"
 
 [registry]
 url = "https://anchor.projectserum.com"

+ 2 - 2
accounts/rent/anchor/programs/create-system-account/Cargo.toml → accounts/rent/anchor/programs/rent-example/Cargo.toml

@@ -1,12 +1,12 @@
 [package]
-name = "create-system-account"
+name = "rent-example"
 version = "0.1.0"
 description = "Created with Anchor"
 edition = "2021"
 
 [lib]
 crate-type = ["cdylib", "lib"]
-name = "create_system_account"
+name = "rent_example"
 
 [features]
 no-entrypoint = []

+ 0 - 0
accounts/rent/anchor/programs/create-system-account/Xargo.toml → accounts/rent/anchor/programs/rent-example/Xargo.toml


+ 15 - 8
accounts/rent/anchor/programs/create-system-account/src/lib.rs → accounts/rent/anchor/programs/rent-example/src/lib.rs

@@ -2,12 +2,11 @@ use anchor_lang::prelude::*;
 use anchor_lang::system_program;
 
 
-declare_id!("6gUwvaZPvC8ZxKuC1h5aKz4mRd7pFyEfUZckiEsBZSbk");
+declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
 
-const LAMPORTS_PER_SOL: u64 = 1000000000;
 
 #[program]
-pub mod create_system_account {
+pub mod rent_example {
     use super::*;
 
     pub fn create_system_account(ctx: Context<CreateSystemAccount>) -> Result<()> {
@@ -15,17 +14,25 @@ pub mod create_system_account {
         msg!("Program invoked. Creating a system account...");
         msg!("  New public key will be: {}", &ctx.accounts.new_account.key().to_string());
 
+        // Determine the necessary minimum rent by calculating the account's size
+        //
+        let account_span = amount as usize;
+        let lamports_required = (Rent::get()?).minimum_balance(account_span);
+
+        msg!("Account span: {}", &account_span);
+        msg!("Lamports required: {}", &lamports_required);
+
         system_program::create_account(
             CpiContext::new(
                 ctx.accounts.system_program.to_account_info(),
                 system_program::CreateAccount {
-                    from: ctx.accounts.payer.to_account_info(),         // From pubkey
-                    to: ctx.accounts.new_account.to_account_info(),     // To pubkey
+                    from: ctx.accounts.payer.to_account_info(),
+                    to: ctx.accounts.new_account.to_account_info(),
                 },
             ),
-            LAMPORTS_PER_SOL,                           // Lamports (1 SOL)
-            32,                                         // Space
-            &ctx.accounts.system_program.key(),         // Owner
+            lamports_required,
+            account_span,
+            &ctx.accounts.system_program.key(),
         )?;
 
         msg!("Account created succesfully.");

+ 2 - 0
accounts/rent/native/package.json

@@ -4,6 +4,8 @@
   },
   "dependencies": {
     "@solana/web3.js": "^1.47.3",
+    "borsh": "^0.7.0",
+    "buffer": "^6.0.3",
     "fs": "^0.0.1-security"
   },
   "devDependencies": {

+ 6 - 18
accounts/rent/native/program/src/lib.rs

@@ -5,7 +5,6 @@ use solana_program::{
     entrypoint::ProgramResult, 
     msg, 
     program::invoke,
-    program_error::ProgramError,
     pubkey::Pubkey,
     rent::Rent,
     system_instruction,
@@ -20,7 +19,7 @@ entrypoint!(process_instruction);
 fn process_instruction(
     _program_id: &Pubkey,
     accounts: &[AccountInfo],
-    _instruction_data: &[u8],
+    instruction_data: &[u8],
 ) -> ProgramResult {
 
     let accounts_iter = &mut accounts.iter();
@@ -33,20 +32,18 @@ fn process_instruction(
 
     // Determine the necessary minimum rent by calculating the account's size
     //
-    let account_span = instruction_data
-        .get(..8)
-        .and_then(|slice| slice.try_into().ok())
-        .map(AddressData::from_le_bytes)
-        .ok_or(ProgramError::InvalidAccountData)?;
+    let account_span = instruction_data.len();
+    let lamports_required = (Rent::get()?).minimum_balance(account_span);
 
-    let lamports_required = (Rent::get()?).minimum_balance(account_span as usize);
+    msg!("Account span: {}", &account_span);
+    msg!("Lamports required: {}", &lamports_required);
     
     invoke(
         &system_instruction::create_account(
             &payer.key,
             &new_account.key,
             lamports_required,
-            account_span,
+            instruction_data.len() as u64,
             &system_program::ID,
         ),
         &[
@@ -56,13 +53,4 @@ fn process_instruction(
 
     msg!("Account created succesfully.");
     Ok(())
-}
-
-
-// Say this is the data structure we intend our account to have
-//
-#[derive(BorshSerialize, BorshDeserialize, Debug)]
-pub struct AddressData {
-    name: String,
-    address: String,
 }

+ 38 - 1
accounts/rent/native/tests/test.ts

@@ -6,6 +6,8 @@ import {
     Transaction,
     TransactionInstruction,
 } from '@solana/web3.js';
+import * as borsh from "borsh";
+import { Buffer } from "buffer";
 
 
 function createKeypairFromFile(path: string): Keypair {
@@ -20,11 +22,46 @@ describe("Create a system account", async () => {
     const connection = new Connection(`http://localhost:8899`, 'confirmed');
     const payer = createKeypairFromFile(require('os').homedir() + '/.config/solana/id.json');
     const program = createKeypairFromFile('./program/target/so/program-keypair.json');
+
+    class Assignable {
+        constructor(properties) {
+            Object.keys(properties).map((key) => {
+                return (this[key] = properties[key]);
+            });
+        };
+    };
+    
+    class AddressData extends Assignable {
+        toBuffer() {
+            return Buffer.from(borsh.serialize(AddressDataSchema, this));
+        }
+    };
+    
+    const AddressDataSchema = new Map([
+        [
+            AddressData, {
+                kind: 'struct',
+                fields: [
+                    ['name', 'string'],
+                    ['address', 'string'],
+                ]
+            }
+        ]
+    ]);
   
     it("Create the account", async () => {
 
         const newKeypair = Keypair.generate();
 
+        const addressData = new AddressData({
+            name: "Marcus",
+            address: "123 Main St. San Francisco, CA"
+        });
+
+        const addressDataBuffer = addressData.toBuffer();
+
+        console.log(`Address data buffer length: ${addressDataBuffer.length}`)
+
         let ix = new TransactionInstruction({
             keys: [
                 {pubkey: payer.publicKey, isSigner: true, isWritable: true},
@@ -32,7 +69,7 @@ describe("Create a system account", async () => {
                 {pubkey: SystemProgram.programId, isSigner: false, isWritable: false}
             ],
             programId: program.publicKey,
-            data: Buffer.alloc(0),
+            data: addressDataBuffer,
         });
 
         await sendAndConfirmTransaction(