# Java与智能合约交互-Read函数 **Published by:** [MrLiuBai](https://paragraph.com/@mrliubai/) **Published on:** 2022-05-07 **URL:** https://paragraph.com/@mrliubai/java-read ## Content 之所以选择利用java与智能合约进行交互,完全是因为本人只会Java,并且Java是世界上最好的语言。 能干什么监控合约状态,读取合约的关键参数,可作为后台数据源。转账、授权等基础交互。实现例如抢购、提挖买等复杂交互。代码分享 1.引入依赖 <dependency> <groupId>org.web3j</groupId> <artifactId>core</artifactId> <version>5.0.0</version> </dependency> 2.新建Web3j对象Web3j web3 = Web3j.build(new HttpService(rpcUrl)); rpcUrl变量是区块链网络节点的url链接,这些节点会提供很多标准的api方法通过该url进行调用,web3j模块就是在此api上进行封装。不同网络的rpcUrl可以在对应的区块链浏览器api文档上找到,百度关键字也很容易获取。3.调用智能合约的只读函数 /** * 读取合约状态 * * @param contractAddress 合约地址 * @param functionName 合约函数名称 * @param input 输入参数 * @param output 返回变量类型 * @return 合约函数返回值 * @throws Exception 与节点交互失败 */ public List<Type> readContract(String contractAddress, String functionName, List<Type> input, List<TypeReference<?>> output) throws Exception { // 生成需要调用函数的data Function function = new Function(functionName, input, output); String data = FunctionEncoder.encode(function); // 组建请求的参数 EthCall response = web3.ethCall( Transaction.createEthCallTransaction(ownerAddress, contractAddress, data), DefaultBlockParameterName.LATEST) .send(); // 解析返回结果 return FunctionReturnDecoder.decode( response.getValue(), function.getOutputParameters()); } contractAddress参数代表智能合约的地址,如"0x123456789..."functionName参数代表需要调用合约中写函数的函数名,比如查询代币余额,该参数传"balanceOf"input参数表示合约函数需要传入的参数,参数类型需要与solidity函数参数类型保持一致例子:Arrays.asList(new Address("0x6dF655480F465DC36347a5616E875D155804F0c5"), new Uint256(10000000));solidity的各类变量类型在web3j库中均有封装output参数表示合约函数返回的参数类型,参数类型需要与solidity函数返回类型保持一致例子:Arrays.asList(new TypeReference(){});solidity函数可能会返回多个不同类型的返回值4.查询代币余额的代码示例 /** * 获取某个代币的余额 * * @param contractAddress 代币合约地址 * @param address 查询用户地址 * @return 余额:单位ether * @throws Exception 与节点交互失败 */ public String balanceOf(String contractAddress, String address) throws Exception { List input = Arrays.asList(new Address(address)); List output = Arrays.asList(new TypeReference<Uint256>() { }); List<Type> result = readContract(contractAddress, "balanceOf", input, output); Uint256 balance = (Uint256) result.get(0); return Convert.fromWei(balance.getValue().toString(), Convert.Unit.ETHER).toString(); } output数组传入的长度决定readContract方法返回值数组的长度1 ether = 1^18 wei,由于链上大部分的代币精度都是18位小数,这里直接做通用处理掌握这些知识点最好的方法是自己将代码跑起来,去链上获取你想获取的信息 ! ## Publication Information - [MrLiuBai](https://paragraph.com/@mrliubai/): Publication homepage - [All Posts](https://paragraph.com/@mrliubai/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@mrliubai): Subscribe to updates