Web3j Java函数调用返回固守合同上的空列表

时间:2018-08-26 18:03:06

标签: java blockchain ethereum web3-java

我正在尝试从此固定合同中调用函数getPrice

pragma solidity ^0.4.0;

contract DataExchangeOfferContract {    
    uint price;

    constructor(uint _price) public {
        price = _price;
    }

    function getPrice() public constant returns (uint) {
        return price;
    }
}

我正在使用geth在调试模式下运行私有区块链客户端,并且部署了具有价值的合同。这是我尝试调用已部署的唯一合同的功能的方法:

EthBlock.Block block = web3j.ethGetBlockByNumber(DefaultBlockParameterName.LATEST, true).send().getBlock();
Transaction transaction = web3j.ethGetTransactionByBlockHashAndIndex(block.getHash(), BigInteger.ZERO).send().getTransaction().get();
String hash = transaction.getHash();

Function function = new Function(DataExchangeOfferContract.FUNC_GETPRICE, Collections.emptyList(), Collections.singletonList(new TypeReference<Uint256>() {}));
String functionEncoder = FunctionEncoder.encode(function);

Transaction transaction = Transaction.createEthCallTransaction(address, functionEncoder, null);
EthCall response = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
List<Type> types = FunctionReturnDecoder.decode(response.getValue(), function.getOutputParameters());
BigInteger price = (BigInteger) types.get(0).getValue();

这里types有0个元素。我在做什么错了?

编辑:

缺少的是合同地址不是交易哈希。 像这样检索合同地址:

EthGetTransactionReceipt transactionReceipt = web3j.ethGetTransactionReceipt(hash).send();
String address = transactionReceipt.getTransactionReceipt().get().getContractAddress();

然后,如响应中所指出的,可以使用合同包装器或使用前面介绍的方法来调用该调用,传递合同地址而不是将交易哈希作为参数

1 个答案:

答案 0 :(得分:2)

如果您的目标是仅从最新的块中获取价格,则说明它变得比所需的更加复杂。假设DataExchangeOfferContract是您生成的存根(您的Solidity代码只说了Contract),则您已经定义了getPrice方法。要使用它,您的代码应如下所示:

Web3j web3j = Web3j.build(new HttpService());

TransactionManager manager = new ReadonlyTransactionManager(web3j, "YOUR_ADDRESS");
DataExchangeOfferContract contract = DataExchangeOfferContract.load("CONTRACT_ADDRESS", web3j, 
                                                                    manager, Contract.GAS_PRICE,
                                                                    Contract.GAS_LIMIT);
RemoteCall<BigInteger> remoteCall = contract.getPrice();
BigInteger price = remoteCall.send();
相关问题