web3j操作和以太坊基础知识

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;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章