??由于最近的项目涉及到区块链,需要做一个使用区块链存储数据的小型系统,区块链是用ethereum搭建的,加上自己一直在学习java(是个菜鸡哈哈哈可以一起交流),所以打算用web3j来与以太坊进行数据流转,发现网上做这个的人是真的少,自己摸索过也遇到了很多坑,(在这里要感谢已经毕业的大师兄@wtlife,帮了我不少忙,祝前程似锦,冲冲冲!)所以将自己遇到的一些问题和踩过的坑都贴出来,让大家少走一点弯路。下面开始正文:
以太坊: ??以太坊的搭建这一块已经有很多前辈们写过了,这里不再赘述,仅将在学习过程中遇到的问题列出来:
- 创世区块写好之后对其进行初始化,这里很莫名其妙,如果直接使用以下命令初始化:
geth --datadir 文件夹名 init genesis.json
会导致挖矿的时候长时间卡顿无法挖到区块,解决方案如下:
geth --datadir 文件夹名称 --networkid 网络号 --rpc --rpccorsdomain “*” init ./genesis.json
再给出启动节点的命令:
geth --datadir data --networkid 网络号 --rpc --rpccorsdomain “*” --nodiscover --port 16333 --rpc port 8546 console
之后正常挖矿即可,为了避免不必要的麻烦,创世区块中的gasLimit建议设置为0xffffff,即最大值。
Ethereum Wallet使用注意点: 【Ethereum+We3j使用小结】??一般来说,自己建立的私链都是使用的默认端口即:8545,但是保不齐该端口经常被占用,所以,在使用该可视化软件部署智能合约时,为了能够正确连接到本地私链,应采用如下方式:
文章图片
本质上其实就是使用rpc调用节点文件夹中的geth.ipc文件。
成功连接之后如下图所示:
文章图片
关于以太坊钱包如何使用,网上也有详细的教程,接下来将使用Java web3j的流程做一个小结。
Web3j: 先给出测试用的智能合约代码,该部分借鉴了@littleredhat1997 的github中的一些资料,不胜感激。
pragma solidity ^0.4.24;
contract Storage{
struct Msg{
string userName;
string ID;
string violateRecord;
uint lowPoint;
string AdministratorName;
}
Msg[] violateRecords;
uint totalMsg=0;
function addMsg(string username,string ID,string violateRecord,uint lowPoint,string AdministratorName ) public{
violateRecords.push(Msg(username,ID,violateRecord,lowPoint,AdministratorName));
}
// function returnTotal() view public returns (uint) {
//return violateRecords.length;
// }
function getuserName(uint id) view public returns (string){
return violateRecords[id].userName;
}
function getID(uint id) view public returns (string){
return violateRecords[id].ID;
}
function getviolateRecord(uint id) view public returns (string){
return violateRecords[id].violateRecord;
}
function getlowPoint(uint id) view public returns (uint){
return violateRecords[id].lowPoint;
}
function getAdministrator(uint id) view public returns (string){
return violateRecords[id].AdministratorName;
}
}
- 使用solc命令生成bin文件和abi文件,需要先安装solc
//如果没有安装npm 需要先安装npm
npm install solc
//会在输出目录生成abi文件和bin文件
solc Storage.sol --bin --abi --optimize - o <输出目录 -dir>/
- 使用web3j命令生成java文件,这一步很重要
web3j solidity generate bin文件的绝对路径 abi文件的绝对路径 -o java文件的目标路径 -p 包名+类名
- 建立web3j和ethereum连接,这里我给出完整的java类,方便同学们学习
- 使用idea编写java程序,使用maven管理web3j Jar包,pom文件的配置如下:
org.web3j
core
4.2.0
- 下面给出完整的与私链通信的java类
import org.web3j.crypto.CipherException;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.RemoteCall;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.core.methods.response.Web3ClientVersion;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.gas.ContractGasProvider;
import java.io.IOException;
import java.math.BigInteger;
public class Test {// GAS价格
public static BigInteger GAS_PRICE = BigInteger.valueOf(20_000_000_000L);
// GAS上限
public static BigInteger GAS_LIMIT = BigInteger.valueOf(4_300_000L);
//合约文件的地址,不会查看的同学可以从将sol文件放入remix中编译获得
public static String ADDORSEARCH_ADDR = "0xc9D1639f492807CbAeEc1ce3B178eCBB171F2Df5";
public static void main(String[] args) throws Exception {
//建立web3j连接,监听私链端口
Web3j web3= Web3j.build(new HttpService("http://localhost:8547"));
Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().send();
String clientVersion = web3ClientVersion.getWeb3ClientVersion();
//连接本地私链的节点,WU.lC(账号的密码,账号对应的钱包文件的绝对路径)
Credentials credentials = WalletUtils.loadCredentials("12345678","/home/qiaozhi/ethereum/data1/keystore/UTC--2019-04-15T08-41-08.880520248Z--6c82e2fef78951b27a7f4c21004e1477cd876c91");
ContractGasProvider provider = new ContractGasProvider() {
@Override
public BigInteger getGasPrice(String s) {
return GAS_PRICE;
}@Override
public BigInteger getGasPrice() {
return GAS_PRICE;
}@Override
public BigInteger getGasLimit(String s) {
return GAS_LIMIT;
}@Override
public BigInteger getGasLimit() {
return GAS_LIMIT;
}
};
// AddorSearch addorSearch = AddorSearch.deploy(web3,credentials,GAS_PRICE,GAS_LIMIT).send();
//该类即为使用web3j命令转换成的java类,包含了sol文件中的所有属性和方法
AddorSearch addorSearch = AddorSearch.load(ADDORSEARCH_ADDR,web3,credentials,provider);
//这里还未完善,sol中应该添加一个length属性,用来循环输出所存储的值
System.out.println(addorSearch.getuserName(BigInteger.valueOf(1)).send().toString());
System.out.println(addorSearch.getID(BigInteger.valueOf(1)).send());
System.out.println(addorSearch.getviolateRecord(BigInteger.valueOf(1)).send());
}
这个项目还没有完善,后期还会进行修改,最近一直在找工作,有时间会上传到我的github上,欢迎大家一起交流!^ _ ^
推荐阅读
- 推动NFT走出监管困境,BSN推出支持NFT基础设施网络
- 腾讯|SaaS的收入模型有哪些(终于有人讲明白了)
- 就业方向上什么才是最重要的(--- 来自程序猿的迷茫。(C++?Java?or算法?))
- 区块链中加密货币的含义
- 波场万倍潜力币HYL23号21:09分 正式上线JustSwap
- 《瀚兰房地产开发区块链应用及案例分享》BSN培训精华回顾
- 对联盟链而言,跨链协议为什么重要()
- 区块链能够应用在哪些行业
- BSN区块链服务网络中密钥托管模式和公钥上传模式有啥区别()
- 币圈人物传|币圈大佬今何在 唯有一诺正当时