java通过智能合约方法调取合约

1、调取只读合约

注意:一般从小狐狸里面复制出来的是没有后面一窜ID的,所以我们需要注册

或者 ,注册完成以后我们可以得到一串ID,将ID拼接在我们的主网络地址后面即可。

  1. 调用智能合约的只读函数
/**
     * 连接web3 节点 https://mainnet.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161
     */
    private final static Web3j web3j = Web3j.build(new HttpService("https://mainnet.infura.io/v3/这里需要拼接上面方法里面获取的ID"));

    public String signTokenTransaction() throws IOException, ExecutionException, InterruptedException {
        try {
            //方法传入的参数为uint
            List input = Arrays.asList(new Uint256(123));
            //返回的是字符串,如果返回格式错误下面解析将会报错
            List output = Arrays.asList(new TypeReference<Utf8String>() {
            });
            //代币合约地址
            String coinAddress = "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d";
            //传入的合约地址、调取的只读方法、传入参数和返回参数
            List<Type> type = readContract(coinAddress,"tokenURI", input,output);
            return type.get(0).toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 读取合约状态
     *
     * @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 = web3j.ethCall(
            Transaction.createEthCallTransaction("0x9175F9EcBbddC078e40C5e037AD31F4abf36628a", 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函数可能会返回多个不同类型的返回值

查询代币余额的代码示例

/**
     * 获取某个代币的余额
     *
     * @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位小数,这里直接做通用处理
经验分享 程序员 微信小程序 职场和发展