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

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

去中心化的开发流程

    1.基础准备

    2.核心开发

        2.1区块链

        2.2java程序

    3.具体案例

去中心化的开发流程

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

1.基础准备

前期准备如下:

IDEA ,你的后台编辑器;

Geth ,你的以太坊区块链本地客户端;

不需要数据库,因为数据可以存储在区块链之上,当然你可以加上。

在线编辑器remix,用来使用solidity语言编写智能合约。

http://remix.hubwiz.com

下载安装web3j命令行。用来把.sol转为.java

2.核心开发

2. 1区块链

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

在本地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 这将确定您在创世纪块中列出的地址有多少以太币可用;

启动区块链

用以下命令初始化区块链,生成创世区块和初始状态。

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交互控制台

使用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 -

2. 2java程序

创建springboot项目

配置pom.xml,加入web3j依赖

配置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

由于项目不需要数据库,注释说明。

在你的xxxApplication.java主函数上添加注释:

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})

在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;

}

调用自己智能合约提供的接口。

两种方式:交易(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类型区别哦

这里也建议大家全程挖矿跑程序,因为部署智能合约以及调用修改数据都需要挖矿的。

大致就写到这里,有什么需要补充的我会在之后补充。

3.具体案例

这里附上个人的实战项目:

https://gitee.com/AidenX/ethereum_blockchain

欢迎各位来学习交流,共同进步。

你可能感兴趣的:(Springboot+web3j完成去中心化的区块链应用)