一、搭建区块链

使用的是FISCO BCOS 和 WeBASE-Front来搭建区块链,详细教程:

https://blog.csdn.net/yueyue763184/article/details/128924144?spm=1001.2014.3001.5501

搭建好能达到下图效果即可:

二、部署智能合约与导出java文件、SDK证书下载

1.创建测试用户,导出pem文件

点击“测试用户”,即可“新增用户”。

点击“导出”,选择.pem文件。

2.编译部署智能合约,导出java文件和SDK证书下载

在“合约IDE”中准备智能合约,新建合约文件,合约名称是Asset。

pragma solidity ^0.4.25;contract Asset {    address public issuer;    mapping (address => uint) public balances;    event Sent(address from, address to, uint amount);    constructor() {        issuer = msg.sender;    }    function issue(address receiver, uint amount) public {        if (msg.sender != issuer) return;        balances[receiver] += amount;    }    function send(address receiver, uint amount) public {        if (balances[msg.sender] < amount) return;        balances[msg.sender] -= amount;        balances[receiver] += amount;        emit Sent(msg.sender, receiver, amount);    }    }

合约IDE会自动保存的,点击“编译”、“部署”后即可得到合约地址contractAddress。

点击“导出java文件”,一般命名与合约名称相同为Asset;

点击“SDK证书下载”;

得到的文件如下:

三、在SpringBoot项目中调用智能合约

1.首先创建SpringBoot项目

2.在pom文件中导入相关依赖

    org.springframework.boot    spring-boot-starter-web    org.springframework.boot    spring-boot-starter-test    test    org.fisco-bcos.java-sdk    fisco-bcos-java-sdk    2.9.1

3.将下载的相关文件导入对应的文件目录(sdk要先解压)

4.在application.yaml配置文件编写fisco的配置

注意:要将路径和合约地址换成自己的

fisco:  nodeList: 192.168.119.138:20201  groupId: 1  certPath: src\main\resources\sdk  contractAddress:    # Asset合约地址(一定要加引号 不然注解@Value会把按照16进制数字进行转换赋值)    asset: "0xc6053e4f71cdcf14e31cc1031263cee4e1ac7768"  # 测试用户地址  account:    # 测试用户秘钥地址    accountAddress: src\main\resources\account    # 测试用户文件地址    accountFilePath: src\main\resources\account\buliangshuai_key_0x3a456344e952d0275e5e4af4766abb450d3b45ac.pem

说明:

fisco.nodeList:区块链节点的ip和端口;
fisco.groupId:组ID;
fisco.certPath:证书保存目录;
fisco.contractAddress.asset:合约地址;
fisco.contractAddress.account.accountAddress:测试用户地址;
fisco.contractAddress.account.accountFilePath:测试用户的pem文件地址;

5.编写sdk访问合约方法

在client包中创建2个类,一个是环境配置类ApplicationContext

package com.fisco.bcos.asset.client;import org.fisco.bcos.sdk.BcosSDK;import org.fisco.bcos.sdk.client.Client;import org.fisco.bcos.sdk.config.ConfigOption;import org.fisco.bcos.sdk.config.exceptions.ConfigException;import org.fisco.bcos.sdk.config.model.ConfigProperty;import org.fisco.bcos.sdk.crypto.CryptoSuite;import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.Arrays;import java.util.HashMap;import java.util.List;import java.util.Map;/** * @Description: 配置类 */@Configurationpublic class ApplicationContext {    @Value("${fisco.nodeList}")    private String nodeLists;    @Value("${fisco.groupId}")    private Integer groupId;    @Value("${fisco.certPath}")    private String certPath;    @Value("${fisco.account.accountFilePath}")    private String accountFilePath;    @Bean(name = "configProperty")    public ConfigProperty defaultConfigProperty() {        ConfigProperty property = new ConfigProperty();        // 配置cryptoMaterial        Map cryptoMaterialMap = new HashMap();        cryptoMaterialMap.put("certPath", certPath);        property.setCryptoMaterial(cryptoMaterialMap);        // 配置network        Map networkMap = new HashMap();        String[] split = nodeLists.split(",");        List nodeList = Arrays.asList(split);        networkMap.put("peers", nodeList);        property.setNetwork(networkMap);        // 配置account        Map accountMap = new HashMap();        accountMap.put("keyStoreDir", "account");        accountMap.put("accountAddress", "");        accountMap.put("accountFileFormat", "pem");        accountMap.put("password", "");        accountMap.put("accountFilePath", accountFilePath);        property.setAccount(accountMap);        //配置 threadPool        Map threadPoolMap = new HashMap();        threadPoolMap.put("channelProcessorThreadSize", "16");        threadPoolMap.put("receiptProcessorThreadSize", "16");        threadPoolMap.put("maxBlockingQueueSize", "102400");        property.setThreadPool(threadPoolMap);        return property;    }    @Bean(name = "configOption")    public ConfigOption defaultConfigOption(ConfigProperty configProperty) throws ConfigException {        return new ConfigOption(configProperty);    }    @Bean(name = "bcosSDK")    public BcosSDK bcosSDK(ConfigOption configOption) {        return new BcosSDK(configOption);    }    @Bean(name = "client")    public Client getClient(BcosSDK bcosSDK) {        // 为群组初始化client        Client client = bcosSDK.getClient(groupId);        return client;    }    @Bean    public CryptoKeyPair getCryptoKeyPair(Client client) {        // 如果有密钥文件 那么每次读取的就不再是随机的        CryptoSuite cryptoSuite = client.getCryptoSuite();        CryptoKeyPair cryptoKeyPair = cryptoSuite.getCryptoKeyPair();        return cryptoKeyPair;    }}

另一个是合约客户端类AssetClient

package com.fisco.bcos.asset.client;import com.fisco.bcos.asset.contract.Asset;import org.fisco.bcos.sdk.BcosSDK;import org.fisco.bcos.sdk.client.Client;import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;import org.fisco.bcos.sdk.model.TransactionReceipt;import org.fisco.bcos.sdk.model.callback.TransactionCallback;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;import java.math.BigInteger;@Componentpublic class AssetClient {    @Autowired    private BcosSDK bcosSDK;    @Autowired    private Client client;    @Autowired    private CryptoKeyPair cryptoKeyPair;    @Value("${fisco.contractAddress.asset}")    private String contractAddress;    /**     * 发布资产(条件:当前用户是Asset合约发布者)     * @param receiver 接收者地址     * @param amount 资产数量     */    public void issueAsset(String receiver, BigInteger amount) {        Asset asset = Asset.load(contractAddress, client, cryptoKeyPair);        asset.issue(receiver, amount, new CallbackResponse());    }    /**     * 发送资产(条件:发送者的账号Balance必须大于等于amount)     * @param receiver 接收者地址     * @param amount 资产数量     */    public void sendAsset(String receiver, BigInteger amount) {        Asset asset = Asset.load(contractAddress, client, cryptoKeyPair);        asset.send(receiver, amount, new CallbackResponse());    }    private class CallbackResponse extends TransactionCallback {        @Override        public void onResponse(TransactionReceipt transactionReceipt) {            System.out.println("回调结果:");            System.out.println(transactionReceipt.getContractAddress());            System.out.println(transactionReceipt.getFrom());            System.out.println(transactionReceipt.getGasUsed());            System.out.println(transactionReceipt.getRemainGas());            System.out.println(transactionReceipt.getStatus());            System.out.println(transactionReceipt.getMessage());            System.out.println(transactionReceipt.getStatusMsg());        }    }}

6.编写测试类调用智能合约函数

首先编写测试类AssetClientTest

package com.fisco.bcos.asset.client;import com.fisco.bcos.asset.AssetDemo1Application;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.math.BigInteger;@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = AssetDemo1Application.class)public class AssetClientTest {    @Autowired    private AssetClient assetClient;    @Test    public void testIssueAsset() throws InterruptedException {        String receiver = "0xc6053e4f71cdcf14e31cc1031263cee4e1ac7768";        BigInteger amount = new BigInteger("10000");        assetClient.issueAsset(receiver, amount);        Thread.sleep(5000);        System.out.println("发布成功!");    }    @Test    public void testSendAsset() throws InterruptedException {        String receiver = "0xc6053e4f71cdcf14e31cc1031263cee4e1ac7768";        BigInteger amount = new BigInteger("50000");        assetClient.sendAsset(receiver, amount);        Thread.sleep(5000);        System.out.println("发送成功!");    }}

测试的步骤:

1)先后执行testIssueAssettestSendAsset测试方法,该测试要保证服务器的20200、20201端口是开放的,命令如下:

firewall-cmd –zone=public –add-port=20201/tcp –permanent # 开放端口

firewall-cmd –zone=public –remove-port=20201/tcp –permanent #关闭端口

firewall-cmd –reload # 配置立即生效

firewall-cmd –zone=public –list-ports #查看防火墙所有开放的端口

2)执行成功后,在节点控制台的“合约列表”中找到对应的合约,点击“合约调用”,选择balances方法;

结果如下:

以上就是在Fisco区块链上部署智能合约,并通过Java SDK调用智能合约函数的示例.