当前位置: 首页 > 工具软件 > Solana > 使用案例 >

145-Solana入门(九)- 合约部署和调用

澹台正业
2023-12-01

人生还很长

路还很长

还有好多事情要做

还有好多人要保护

为什么人们总是不快乐

欲望太强

内心太弱

希望自己可以和这个世界更好地相处

不要反反复复地陷入漩涡

今天来看一下最简单的合约部署和调用

我们拿anchor的示例代码来举例

use anchor_lang::prelude::*;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
mod basic_0 {
    use super::*;
    pub fn initialize(_ctx: Context<Initialize>) -> Result<()> {
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize {}

这段是最简单的代码,这里的declare_id等一下是要修改掉的

我们先编译一下

运行

anchor build

编译成功

然后在target/deploy这个文件夹下面

生成了so文件和keypair的json文件

我们需要读取一下keypair的公钥,也就是地址

进入deploy文件夹,输入命令

solana address -k my_anchor_test-keypair.json

生成的地址是

2MFi9ah4oca2PCADoT5tDxP6UYi4K3smTQEhSB779FHZ

然后我们把这个地址复制到declare_id里面去

use anchor_lang::prelude::*;

declare_id!("2MFi9ah4oca2PCADoT5tDxP6UYi4K3smTQEhSB779FHZ");

#[program]
mod basic_0 {
    use super::*;
    pub fn initialize(_ctx: Context<Initialize>) -> Result<()> {
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize {}

然后我们重新编译一下

anchor build

编译成功

重新编译会生成新的so文件

然后我们来部署一下

可以用solana airdrop 2来搞一点测试币

然后部署一下

solana program deploy my_anchor_test.so

部署成功

~/my_anchor_test/target/deploy# solana program deploy my_anchor_test.so
Program Id: 2MFi9ah4oca2PCADoT5tDxP6UYi4K3smTQEhSB779FHZ

然后我们来调用一下这个程序

我是在react里面调的

先写个方法初始化钱包

const initWallet = async () => {
    const isPhantomInstalled = window.solana && window.solana.isPhantom;
    console.log(isPhantomInstalled);
    try {
        const resp = await window.solana.connect();
        console.log(resp.publicKey.toString())
    } catch (err) {
        // { code: 4001, message: 'User rejected the request.' }
        console.log(err)
    }
}

然后写个方法创建provider

const getProvider = () => {
    // const network = "http://127.0.0.1:8899";
    const network = "https://api.devnet.solana.com";
    const connection = new Connection(network);
    const provider = new AnchorProvider(connection, window.solana, AnchorProvider.defaultOptions(),);
    return provider;
};

然后我们来调用一下

async function test01() {

    //init wallet
    await initWallet();

    //set provider
    const provider = getProvider();
    anchor.setProvider(provider);

    //get idl
    const idl = abi_hello;

    //create program
    const programAddress = "2MFi9ah4oca2PCADoT5tDxP6UYi4K3smTQEhSB779FHZ";
    const programId = new anchor.web3.PublicKey(programAddress);
    const program = new anchor.Program(idl, programId);

    //execute rpc
    const result = await program.rpc.initialize();
    console.log(result)

}

然后我们来看一下完整的代码

import {Button, StyleSheet, View} from 'react-native';
import React from "react";
import {abi_hello} from "./abi";
import {Connection} from '@solana/web3.js';
import * as anchor from '@project-serum/anchor';
import {AnchorProvider} from '@project-serum/anchor';

export function SettingsScreen({navigation}) {
    return (
        <View style={styles.container}>
            <Button title='test' onPress={() => test01()}/>
        </View>
    );
}

const initWallet = async () => {
    const isPhantomInstalled = window.solana && window.solana.isPhantom;
    console.log(isPhantomInstalled);
    try {
        const resp = await window.solana.connect();
        console.log(resp.publicKey.toString())
    } catch (err) {
        // { code: 4001, message: 'User rejected the request.' }
        console.log(err)
    }
}

const getProvider = () => {
    // const network = "http://127.0.0.1:8899";
    const network = "https://api.devnet.solana.com";
    const connection = new Connection(network);
    const provider = new AnchorProvider(connection, window.solana, AnchorProvider.defaultOptions(),);
    return provider;
};

async function test01() {

    //init wallet
    await initWallet();

    //set provider
    const provider = getProvider();
    anchor.setProvider(provider);

    //get idl
    const idl = abi_hello;

    //create program
    const programAddress = "2MFi9ah4oca2PCADoT5tDxP6UYi4K3smTQEhSB779FHZ";
    const programId = new anchor.web3.PublicKey(programAddress);
    const program = new anchor.Program(idl, programId);

    //execute rpc
    const result = await program.rpc.initialize();
    console.log(result)

}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#9ff',
        alignItems: 'center',
        justifyContent: 'center',
    }
});

这里用的都是和phantom钱包交互的

所以要安装phantom钱包

在网页上面调用一下

成功了

然后我们再看anchor的第二个例子

先看下合约代码

我们把declare_id换成我们现在的这个programId

然后我们重新部署一下

现在这个程序相当于覆盖了之前的basic_0程序

然后我们来调用一下

记得我们要使用新的idl

idl就在我们编译之后的targer/idl文件夹下面

我们来看一下完整代码

import {Button, StyleSheet, View} from 'react-native';
import React from "react";
import {abi_basic_1} from "./abi";
import {Connection, SystemProgram} from '@solana/web3.js';
import * as anchor from '@project-serum/anchor';
import {AnchorProvider} from '@project-serum/anchor';

export function SettingsScreen({navigation}) {
    return (
        <View style={styles.container}>
            <Button title='test' onPress={() => test01()}/>
        </View>
    );
}

const initWallet = async () => {
    const isPhantomInstalled = window.solana && window.solana.isPhantom;
    console.log(isPhantomInstalled);
    try {
        const resp = await window.solana.connect();
        console.log(resp.publicKey.toString())
    } catch (err) {
        // { code: 4001, message: 'User rejected the request.' }
        console.log(err)
    }
}

const getProvider = () => {
    // const network = "http://127.0.0.1:8899";
    const network = "https://api.devnet.solana.com";
    const connection = new Connection(network);
    const provider = new AnchorProvider(connection, window.solana, AnchorProvider.defaultOptions(),);
    return provider;
};

async function test01() {

    //init wallet
    await initWallet();

    //set provider
    const provider = getProvider();
    anchor.setProvider(provider);

    //get idl
    const idl = abi_basic_1;

    //create program
    const programAddress = "2MFi9ah4oca2PCADoT5tDxP6UYi4K3smTQEhSB779FHZ";
    const programId = new anchor.web3.PublicKey(programAddress);
    const program = new anchor.Program(idl, programId);

    //create account
    const myAccount = anchor.web3.Keypair.generate();

    //execute rpc
    const result = await program.rpc.initialize(new anchor.BN(1234), {
        accounts: {
            myAccount: myAccount.publicKey,
            user: provider.wallet.publicKey,
            systemProgram: SystemProgram.programId,
        },
        signers: [myAccount],
    });
    console.log(result)

}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#9ff',
        alignItems: 'center',
        justifyContent: 'center',
    }
});

然后我们看anchor的basic_2

use anchor_lang::prelude::*;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
mod basic_2 {
    use super::*;

    pub fn create(ctx: Context<Create>, authority: Pubkey) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.authority = authority;
        counter.count = 0;
        Ok(())
    }

    pub fn increment(ctx: Context<Increment>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.count += 1;
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Create<'info> {
    #[account(init, payer = user, space = 8 + 40)]
    pub counter: Account<'info, Counter>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(mut, has_one = authority)]
    pub counter: Account<'info, Counter>,
    pub authority: Signer<'info>,
}

#[account]
pub struct Counter {
    pub authority: Pubkey,
    pub count: u64,
}

我们把declare_id改掉,然后编译一下

然后部署一下

solana program deploy xxx.so

然后我们看一下调用

import {Button, StyleSheet, View} from 'react-native';
import React from "react";
import {Connection, PublicKey, SystemProgram} from '@solana/web3.js';
import * as anchor from '@project-serum/anchor';
import {AnchorProvider} from '@project-serum/anchor';
import {abi_basic_2} from "./abi";

export function SettingsScreen({navigation}) {
    return (
        <View style={styles.container}>
            <Button title='test' onPress={() => test01()}/>
        </View>
    );
}

const initWallet = async () => {
    const isPhantomInstalled = window.solana && window.solana.isPhantom;
    console.log(isPhantomInstalled);
    try {
        const resp = await window.solana.connect();
        console.log(resp.publicKey.toString())
    } catch (err) {
        // { code: 4001, message: 'User rejected the request.' }
        console.log(err)
    }
}

const getProvider = () => {
    // const network = "http://127.0.0.1:8899";
    const network = "https://api.devnet.solana.com";
    const connection = new Connection(network);
    const provider = new AnchorProvider(connection, window.solana, AnchorProvider.defaultOptions());
    return provider;
};

async function test01() {

    //init wallet
    await initWallet();

    //set provider
    const provider = getProvider();
    anchor.setProvider(provider);

    //get idl
    const idl = abi_basic_2;

    //create program
    const programAddress = "AQjihFJtGskyaEn6e6xagBZkoGQ9V31Y9AG2cuC2uDJU";
    const programId = new PublicKey(programAddress);
    const program = new anchor.Program(idl, programId);

    //create account
    const myAccount = anchor.web3.Keypair.generate();
    console.log(myAccount.publicKey.toBase58());

    //execute rpc
    const result = await program.rpc.create(provider.wallet.publicKey, {
        accounts: {
            counter: myAccount.publicKey,
            user: provider.wallet.publicKey,
            systemProgram: SystemProgram.programId,
        },
        signers: [myAccount],
    });
    console.log(result)
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#9ff',
        alignItems: 'center',
        justifyContent: 'center',
    }
});

 类似资料: