合约中调用外部合约函数时,提示Couldn’t decode uint256 from ABI

appchain

#1

cita 0.17 在A合约中用new的方式构造B合约后,调用B合约的成员函数,出现Couldn’t decode uint256 from ABI的错误。同样的合约在以太坊测试网上是可以运行的。

合约A:
pragma solidity ^0.4.16;
import “./Test2.sol”;

contract Test1 {

Test2 public test2;

function Test1() {
}

function setTest2(address _address) {
    test2 = Test2(_address);
}

function getTest2Value() constant returns (uint256 test2value) {
    return test2.getValue();
}

function getValue() returns (uint256 value) {
    return 128;
}

}

合约B:
pragma solidity ^0.4.16;

contract Test2 {

function Test2() {
}

function getValue() constant returns (uint256 value) {
    return 256;
}

}

合约在js中的使用方法:
let test1Ins = null;
let test2Ins = null;
let test2Address = ‘’;
this.web3.appchain.getBlockNumber()
.then((blockNumber) => {
tx.validUntilBlock = blockNumber + 88;
test1Ins = new this.web3.appchain.Contract(Test1[‘abi’]);
return test1Ins.deploy({data: Test1[‘bytecode’]})
.send(tx);
}).then(txRes => {
return this.web3.listeners.listenToTransactionReceipt(txRes.hash);
}).then( receipt => {
alert("Test1’s receipt is : " + JSON.stringify(receipt));
this.saleAuctionContractAddress = receipt.contractAddress;
console.log('auction address is ’ + receipt.contractAddress);
test1Ins.options.address = receipt.contractAddress;
return test1Ins.methods.getValue().call();
}).then(res => {
alert("Test1’s value is " + res);
return this.web3.appchain.getBlockNumber();
}).then(blockNumber => {
tx.validUntilBlock = blockNumber + 88;
test2Ins = new this.web3.appchain.Contract(Test2[‘abi’]);
return test2Ins.deploy({data: Test2[‘bytecode’]})
.send(tx);
}).then(txRes => {
return this.web3.listeners.listenToTransactionReceipt(txRes.hash);
}).then( receipt => {
alert("Test2 Receipt is : " + JSON.stringify(receipt));
this.saleAuctionContractAddress = receipt.contractAddress;
console.log('auction address is ’ + receipt.contractAddress);
test2Ins.options.address = receipt.contractAddress;
test2Address = receipt.contractAddress;
return test2Ins.methods.getValue().call();
}).then(res => {
alert("Test2’s value is " + res);
return this.web3.appchain.getBlockNumber();
}).then(blockNumber => {
tx.validUntilBlock = blockNumber + 88;
return test1Ins.methods.setTest2(test2Address).send(tx);
}).then(res => {
return this.web3.listeners.listenToTransactionReceipt(res.hash);
}).then(receipt => {
alert("SetTest2 Receipt is : " + JSON.stringify(receipt));
return test1Ins.methods.getTest2Value().call();
}).then(res => {
alert("Test2’s in test1 is " + res);
}).catch(e => {
alert("Exception: " + e);
})


#2

打印一下最后调用函数时候的原始的rpc call的返回信息

另外,描述中

cita 0.17 在A合约中用new的方式构造B合约后,调用B合约的成员函数

看后面代码应该是连续部署两个合约,调用A的函数。不要用new,容易误导。
new的用法


#3

test1Ins.methods.getTest2Value().call(), 这个操作没有出现transaction


#4

恩,我已经修改了。看一下rpc的返回信息,不是sdk decode之后的信息


#5

这里和rpc有关系吗?


#6

你这里实际调用的是jsonRPC的call方法啊 call


#7

我在appchain/contract/index.js中的 outputFormatter 添加了 alert, 结果是result = 0x
case Action.CALL:
const call = new Method({
name: ‘call’,
call: Action.CALL,
params: 2,
inputFormatter: [
formatters.inputCallFormatter,
formatters.inputDefaultBlockNumberFormatter
],
outputFormatter: function (result) {
alert(result);
return ctx._parent._decodeMethodReturn(ctx._method.outputs, result);
},


#8

@kaikai 你是在官方测试链上修改的吗?


#9

ok,0x是call没成功。你升级一下版本试试,如果升级之后ok可能就是bug


#10

是升级appchain的版本?还是本地truffle对应的solidity的版本?


#11

升级solidity的版本,目前我们用的是0.4.24


#12

我试着把升级到0.4.24,还是一样的问题


#13

@kaikai 我把本地的solc编译器从0.4.23降级到0.4.18, 就OK了,这个应该是solc或者是truffle的bug.


#14

这个我这边记下来,回头复现一下。也有可能是一些特定版本的特性vm没有支持