3

我正在尝试getPrice从此solidity合约中调用该函数

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();

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

4

1 回答 1

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();
于 2018-08-26T22:40:29.437 回答