用Springboot+web3j完成去中心化的以太坊区块链应用(附带实战案例)

Springboot+web3j完成去中心化的区块链应用

  • 去中心化的开发流程
    • 基础准备
    • 核心开发
      • 区块链
      • java程序
    • 具体案例

去中心化的开发流程

简单分析下本人的小小开发经历,当初自己学习的时候翻看很多资料也一头雾水,白花了很多力气,这里进行简要总结,希望为大家带来帮助。

基础准备

前期准备如下:

  1. IDEA ,你的后台编辑器;
  2. Geth ,你的以太坊区块链本地客户端;
  3. 不需要数据库,因为数据可以存储在区块链之上,当然你可以加上。
  4. 在线编辑器remix,用来使用solidity语言编写智能合约。
    http://remix.hubwiz.com
  5. 下载安装web3j命令行。用来把.sol转为.java

核心开发

区块链

  1. 用solidity语言设计你的智能合约,数据结构用struct存储于以太坊区块链上,调试运行在remix的虚拟机上。

  2. 在本地geth客户端上创建创世区块。
    首先配置私有区块链网络的初始状态。新建一个文件 genesis.json
    {
    “config”: {
    “chainId”: 22,
    “homesteadBlock”: 0,
    “eip150Block”: 0,
    “eip155Block”: 0,
    “eip158Block”: 0,
    “byzantiumBlock”: 0,
    “constantinopleBlock”: 0,
    “petersburgBlock”: 0,
    “ethash”: {}
    },
    “difficulty”: “1”,
    “gasLimit”: “0xffffffff”,
    “alloc”: {}
    }
    其中需要修改的配置
    •chainId 指定了独立的区块链网络 ID,不同 ID 网络的节点无法互相连接;
    •ethash 使用ethash共识算法;
    •difficulty 初始挖掘难度,难度越大越难挖到区块;
    •gasLimit 用于限制单个块中可以进行多少EVM计算,这里值得一提,那就是我配置的最大,因为我的智能合约功能很复杂花费的gas很多。
    •alloc 这将确定您在创世纪块中列出的地址有多少以太币可用;

  3. 启动区块链
    用以下命令初始化区块链,生成创世区块和初始状态。
    geth init genesis.json
    然后用以下命令启动节点进入Javascript交互控制台
    geth --nodiscover --rpc --rpcapi db,eth,net,web3 --allow-insecure-unlock console
    各选项的含义如下:
    •–nodiscover 关闭区块链节点发现机制;
    •–rpc 开启以太坊HTTP-RPC 服务(默认端口8545);
    •–rpcapi 默认情况下,出于安全原因,并非所有功能都通过RPC接口提供。需要指定需要开放的功能;
    •–allow-insecure-unlock 允许不安全的解锁用户操作。
    •console 进入Javascript交互控制台

  4. 使用web3j命令行工具转义智能合约(从.sol->.java)
    编译合约生成Java包装器
    首先我们需要将sol合约文件编译成EVM字节码和ABI,这里我们使用solc来编译合约,在当前目录会生成两个文件,分别是字节码文件和abi文件。如果solcjs命令不存在,需要先用npm安装solc。
    #npm install -g solc 安装solc
    solcjs xxx(你的智能合约).sol --bin --abi --optimize -o xxx(输出目录)
    然后使用web3j命令行工具生成Java包装类。各命令的含义如下:
    •-b 指定bin文件;
    •-a 指定abi文件;
    •-o 指定生成的Java文件路径;
    •-p 指定生成Java文件的包名;
    •-c 指定生成的类名
    web3j solidity generate -b xxx.bin -a xxx.abi -o …/java -

java程序

  1. 创建springboot项目

  2. 配置pom.xml,加入web3j依赖
    用Springboot+web3j完成去中心化的以太坊区块链应用(附带实战案例)_第1张图片

  3. 配置application.properties
    #1.项目启动的端口
    server.port=18902
    #2.web3j配置
    web3j.client-address: http://127.0.0.1:8545
    web3j.admin-client=true
    web3j.http-timeout-seconds=600
    spring.thymeleaf.encoding=UTF-8
    spring.thymeleaf.mode=HTML
    spring.thymeleaf.cache=false
    debug=true
    #热部署,使得静态资源不需要重启
    spring.devtools.restart.exclude=/static/
    #重启目录
    spring.devtools.restart.additional-paths=src/main/java

  4. 由于项目不需要数据库,注释说明。
    在你的xxxApplication.java主函数上添加注释:
    @SpringBootApplication(exclude={DataSourceAutoConfiguration.class})

  5. 在java程序中使用web3j进行和区块链之间的交互。
    展示几个关键的重要的(其中Diploma为我的智能合约类):
    //部署智能合约
    public Diploma deployContract()throws Exception {
    Diploma diploma = Diploma.deploy(web3j,credentials,Contract.GAS_PRICE, Contract.GAS_LIMIT).send();
    return diploma;
    }

    //加载智能合约
    public Diploma loadContract() {
    Diploma diploma = Diploma.load(ContractAddress, web3j, credentials, new BigInteger(“21000”), new BigInteger(“35000000000”));
    return diploma;
    }

    //注册账户
    public String Regist()throws Exception {
    String walletFileName="";//文件名
    String walletFilePath=“C:\Users\xxx\AppData\Roaming\Ethereum\keystore”;
    //钱包文件保持路径,请替换位自己的某文件夹路径
    walletFileName = WalletUtils.generateNewWalletFile(“123456”, new File(walletFilePath), false);
    Credentials new_credentials = WalletUtils.loadCredentials(password, walletFilePath + “\” + walletFileName);
    String address = new_credentials.getAddress();
    return address;
    }

  6. 调用自己智能合约提供的接口。
    两种方式:交易(transaction)方式以及function方式。
    transaction方式增删改查都可以使用,但是需要挖矿来处理数据,速度会慢。function方式只可以使用于查,但是速度快。因此建议所有的查询都用function方式。
    transaction方式用法:
    Diploma diploma=smartContract.loadContract();
    TransactionReceipt a=diploma.comfirmEdu(address).sendAsync().get();
    List b = diploma.getEventResponseLogEvents(a);
    return b.get(0).message.equals(“ok”);
    ps:transaction方式需要event证明接口执行状态。

    function方式用法:
    List inputParameters = new ArrayList<>();
    inputParameters.add(new Address(AdminAccountID));
    inputParameters.add(new Utf8String(id));
    inputParameters.add(new Utf8String(password));
    List> outputParameters= new ArrayList<>();
    TypeReferencebool=new TypeReference() {
    };
    outputParameters.add(bool);
    Function function = new Function(“接口函数名称”,
    inputParameters,outputParameters);
    String encodedFunction = FunctionEncoder.encode(function);
    org.web3j.protocol.core.methods.response.EthCall response = Web3JClient.getClient().ethCall(
    Transaction.createEthCallTransaction(AdminAccountID, smartContract.ContractAddress, encodedFunction),
    DefaultBlockParameterName.LATEST)
    .sendAsync().get();
    //获取返回结果
    List result = FunctionReturnDecoder.decode(
    response.getValue(), function.getOutputParameters());
    if (result.size()==0)
    return false;
    boolean login_ok=Boolean.parseBoolean(result.get(0).getValue().toString());
    return login_ok;
    ps:function方式需要注意web3j数据类型和你需要的java类型区别哦
    这里也建议大家全程挖矿跑程序,因为部署智能合约以及调用修改数据都需要挖矿的。
    大致就写到这里,有什么需要补充的我会在之后补充。

具体案例

这里附上个人的实战项目:
https://gitee.com/AidenX/ethereum_blockchain
欢迎各位来学习交流,共同进步。

你可能感兴趣的:(web开发,java,区块链,区块链,spring,boot,java)