搜索了很多内容,发现目前很多文章还在引入
1.6.0 版本,这里版本早已更新,虽然release还没有
https://github.com/web3j/web3j-spring-boot-starter
更多信息
http://docs.web3j.io/4.8.7/references/developer_guide/
Maven 依赖
org.web3j
web3j-spring-boot-starter
4.0.3
org.web3j
core
5.0.0
com.squareup.okhttp3
okhttp
4.3.1
org.web3j
web3j-maven-plugin
4.8.7
使用
环境准备
- ganache
- metamask
- 自己搭建的私有链(可选)基于docker的以太坊集群的私有链开发环境
代码仓库
https://gitee.com/simonzz/springboot-web3js-demo.git
- 追加bean
@Bean
public Web3j web3j() {
String ip = "http://localhost:9545";
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.connectTimeout(30*1000, TimeUnit.MILLISECONDS);
builder.writeTimeout(30*1000, TimeUnit.MILLISECONDS);
builder.readTimeout(30*1000, TimeUnit.MILLISECONDS);
OkHttpClient httpClient = builder.build();
return Web3j.build(new HttpService(ip,httpClient,false));
}
- 使用
# 注入 Web3j
@Autowired
private Web3j web3j;
# demo 公私钥,可在ganache中取得
private String fromAddr = "0x9bB1BB52f78B4AA7d913D3afA9F64565407F8103";
private String fromPrivateKey = "5ee21f66d20976a428e7cd242df1d7775eca1179ad0df6530f7a0ed00f15ac3d";
private String toAddr = "0xd59728Da828F587196c8e5d58437C7c76c6Fc888";
- 获取GasPrice,价格是以Wei为单位计算的
public BigInteger getGasPrice() throws IOException {
EthGasPrice ethGasPrice = web3j.ethGasPrice().send();
BigInteger gasFee = ethGasPrice.getGasPrice();
log.info("web3 ethGasPrice: {}", ethGasPrice.getGasPrice().longValue());
return gasFee;
}
- 获取公钥资产余额
public BigInteger getBalance(String fromAddr) throws IOException {
EthGetBalance ethGetBalance = web3j.ethGetBalance(fromAddr, DefaultBlockParameterName.LATEST)
.send();
BigInteger balance = ethGetBalance.getBalance();
log.info("web3 balance: {}", balance.longValue());
return balance;
}
- 获取随机数nonce
public BigInteger getNonce(String fromAddr) throws IOException {
EthGetTransactionCount transactionCount = web3j
.ethGetTransactionCount(fromAddr, DefaultBlockParameterName.LATEST).send();
BigInteger nonce = transactionCount.getTransactionCount();
log.info("web3 nonce:{}", nonce.longValue());
return nonce;
}
- 创建无签名的transaction
public void createTransaction(BigDecimal amount) throws IOException {
BigInteger nonce = getNonce(fromAddr);
BigInteger ethGasPrice = getGasPrice();
BigInteger transferAmount = Convert.toWei(amount, Unit.ETHER).toBigInteger();
log.info("transferAmount:{} = amount:{}", transferAmount, amount);
Transaction etherTransaction = Transaction
.createEtherTransaction(fromAddr, nonce, ethGasPrice,
null, toAddr, transferAmount);
// 估算gasLimit
EthEstimateGas ethEstimateGas = web3j.ethEstimateGas(etherTransaction).send();
log.info("EthEstimateGas: {}", ethEstimateGas.getAmountUsed());
// 调用查看余额 wei为单位
BigInteger biBalance = getBalance(fromAddr);
log.info("balance:{}", biBalance);
// total amount
BigInteger totalAmount = transferAmount.add(ethEstimateGas.getAmountUsed());
log.info("totalAmount:{}", totalAmount);
if (totalAmount.compareTo(biBalance) >= 0) {
log.error("余额不足!!");
return;
}
EthSendTransaction send = web3j.ethSendTransaction(etherTransaction).send();
log.info("no sign result: {}", JSONUtil.toJsonStr(send));
}
- 发送签名转账
/**
* 私钥签名转账
* @param to 接收账户
* @param transferAmount 转账多少ETH
* @param privateKey 发起者私钥
* @param chainId 链ID
* @throws IOException
*/
public void signTransactionAndSend(String to,
BigDecimal transferAmount, String privateKey, Long chainId)
throws IOException {
BigInteger nonce = getNonce(fromAddr);
BigInteger gasPrice = getGasPrice();
BigInteger gasLimit = Convert.toWei(GAS_LIMIT, Unit.WEI).toBigInteger();
BigInteger value = Convert.toWei(transferAmount, Unit.ETHER).toBigInteger();
String txHash = "";
RawTransaction transaction = RawTransaction
.createTransaction(nonce, gasPrice, gasLimit, to, value, "");
// 私钥进行判断 去掉0x
if (privateKey.startsWith("0x")) {
privateKey = privateKey.substring(2);
}
ECKeyPair ecKeyPair = ECKeyPair.create(new BigInteger(privateKey, 16));
Credentials credentials = Credentials.create(ecKeyPair);
byte[] signMessage;
if (!Objects.isNull(chainId)) {
signMessage = TransactionEncoder.signMessage(transaction, chainId, credentials);
} else {
signMessage = TransactionEncoder.signMessage(transaction, credentials);
}
String signData = Numeric.toHexString(signMessage);
log.info("signData: {}", signData);
if (!"".equals(signData)) {
EthSendTransaction send = web3j.ethSendRawTransaction(signData).send();
log.info("result: {}", JSONUtil.toJsonStr(send));
txHash = send.getTransactionHash();
}
log.info("txHash: {}", txHash);
}