web3j操作和以太坊基礎知識
以太坊中的基本單位
單位很多,主要需要關注的是下面3種。
- 最小單位是wei
- 其中 ether就是常說的1個ETH。1個ETH是1e18 wei。
- 1個Gwei就是常說的gas,一個gas即一個Gwei=1e9 wei。
單位 | wei值 | Wei |
---|---|---|
wei | 1 | 1 wei |
Gwei (shannon) | 1e9 wei | 1,000,000,000 |
ether | 1e18 wei | 1,000,000,000,000,000,000 |
web3j操作
官方提供jar包可供java開發者與鏈交互,如餘額查詢、發佈合約、發交易等。
maven座標如下所示,其中core是各種API用來做交互的,codegen是用來將合約的abi文件生成java的操作類,類似於gRPC的skeleton生成對應stub文件。具體業務代碼使用時直接當作工具類一樣調用即可。
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.web3j</groupId>
<artifactId>codegen</artifactId>
<version>5.0.0</version>
</dependency>
查詢原生幣餘額
如果是鏈的原生幣(如ETH相對於以太坊),則直接調用web3j.ethGetBalance()方法即可查詢地址的餘額。需要注意的是這裏的餘額是需要做精度處理的,詳見[以太坊中的基本單位](# 以太坊中的基本單位) ,這裏返回的餘額單位是wei,要轉換成ETH,需要除以
1e18
如果是穩定幣,則需要調用合約地址進行查詢,因爲穩定比都是通過發佈智能合約實現的。
public BigDecimal getBalance(String symbol, String address) {
Web3j web3j = Web3jWrapper.get(ChainNetworkEnum.PlatON);
try {
BigInteger balance;
// 原生幣直接通過地址查詢,USDC,USDT用合約查詢
if(symbol.equals(TokenSymbolEnum.LAT.getDesc())){
balance = web3j.ethGetBalance(address, DefaultBlockParameterName.LATEST).send().getBalance();
int decimal = SystemConfig.CHAIN_CONFIG_MAP.get(ChainNetworkEnum.PlatON.getChainCode()).getDecimals();
return AmountHandleUtils.device(new BigDecimal(balance), decimal);
}else {
TAssetsConfig tAssetsConfig = SystemConfig.ASSET_CONFIG_MAP.get(symbol);
String contractAddress= tAssetsConfig.getAddress();
TransactionManager transactionManager = new ReadonlyTransactionManager(web3j, address);
ERC20 erc20 = ERC20.load(contractAddress, web3j, transactionManager, new DefaultGasProvider());
balance = erc20.balanceOf(address).send();
return AmountHandleUtils.device(new BigDecimal(balance), tAssetsConfig.getDecimals());
}
} catch (Exception e) {
log.error("getBalance error", e);
throw new BusinessException(BaseResultEnum.GET_BALANCE_EXCEPTION);
}
}
查詢預估gas費用
private BigInteger getEstimateGasUsed(BigInteger gasPrice) {
//查詢三方接口預估gasUsed發生異常時直接取默認值
BigInteger gasUsed = BigInteger.valueOf(Long.parseLong(SystemConfig.SYSTEM_CONFIG_MAP.get(SystemConfigEnum.LAT_ESTIMATE_GAS_USED_DEFAULT_VALUE.getKey())));
try {
BigInteger value = Convert.toWei("0.0001", Convert.Unit.GWEI).toBigInteger();
final org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(ERC20.FUNC_TRANSFER,
Arrays.asList(new Address(160, "0x9D12656c3f14A35744874FA5A5d89a33B7354bf1"), new Uint256(value)), Collections.emptyList());
String data = FunctionEncoder.encode(function);
// 拼交易Transaction
Transaction transaction=new Transaction(
senderAddress,
BigInteger.ZERO,
gasPrice,
// new DefaultGasProvider().getGasLimit(),
null,
"0x9D12656c3f14A35744874FA5A5d89a33B7354bf1",
value,
data
);
// 估算gasUsed
gasUsed = platOnChainManager.getEstimateGas(transaction);
} catch (Exception e) {
log.error("getEstimateGasUsed error", e);
}
return gasUsed;
}