坚固性:从另一个合同调用功能时发生错误

时间:2018-08-27 13:32:31

标签: solidity

面对我一个非常不清楚的问题。有两个简单的合同:

contract Test1 {
    int128 public val;    
    function getVal() view public returns(int128) {
        return val;
    }    
    function setVal( int128 _val ) public {
        val = _val;
    }
}

contract Test2 {
    address public the1;    
    function setTest1( address _adr ) public {
        the1 = _adr;
    }    
    function setVal( int128 _val ) public {
        Test1( the1 ).setVal( _val );
    }    
    function getVal() view public returns(int128) {
        return Test1( the1 ).getVal();
    }    
}

您可以将字段Test1.val的值更改为在Test1合约中调用函数setVal和在Test2中调用相同的函数(当然是在第二个Test2.setTest1中设置了第一个合约的地址之后)。

在Remix和测试中(ganache)–一切正常。但是在专用网络(通过Geth实现)上,我遇到了麻烦:当我调用Test2.setVal时–值已更改; 当我调用Test2.getVal时–不起作用。我通过web3j拨打电话

test2.setVal( BigInteger.valueOf(30)).send();
result = test2.getVal().send(); // (1)

在(1)点有一个例外:

ContractCallException: Emtpy value (0x) returned from contract.

我不知道这有什么问题。从另一个合约中调用函数的机制非常简单。但是我不明白自己在做什么。

我试图调用contract的函数抛出geth-console。在这种情况下,没有错误,只是Test2.getVal()返回0。

任何想法我都会感激!

更新。这是测试(我使用@Ferit的测试)

const TEST_1 = artifacts.require('Test1.sol');
const TEST_2 = artifacts.require('Test2.sol'); 

contract('Ferit Test1', function (accounts) {

  let test1;
  let test2;

  beforeEach('setup contract for each test case', async () => {
    test1 = await TEST_1.at("…");
    test2 = await TEST_2.at("…");   
    })

  it('test1', async () => {
      await test1.setVal(333);
      let result = await test1.getVal();
      console.log( "-> test1.getVal=" + result );   
      assert(result.toNumber(), 333 );
  })

  it('test2', async () => {
      await test2.setVal(444);
      let result = await test2.getVal(); // (!!!) return 0
      console.log( "-> test2.getVal=" + result );   
      assert(result.toNumber(), 444);
  })
})

2 个答案:

答案 0 :(得分:0)

问题1 .send()。应该删除。

问题2 :您确定已将测试1实例的地址传递给了测试2?

问题3 :您需要异步调用它们。在您的测试文件中,我没有看到任何异步/等待或任何promise子句。

我所做的更改:

  • 将合同移动到相应的文件(Test1.sol和Test2.sol)。
  • 通过删除.send()
  • 修复了测试文件中的问题1
  • 通过将Test1实例的地址传递给Test2来修复测试文件中的问题2
  • 使用async / await语法修复了测试文件中的问题3。

固定的测试文件如下:

const TEST_1 = artifacts.require('Test1.sol');
const TEST_2 = artifacts.require('Test2.sol');


contract('Test1', function (accounts) {

  let test1;
  let test2;

  beforeEach('setup contract for each test case', async () => {
    test1 = await TEST_1.new({from: accounts[0]});
    test2 = await TEST_2.new({from: accounts[0]});
    await test2.setTest1(test1.address); // Problem 2
  })

  it('should let owner to send funds', async () => {
      await test2.setVal(30); // Problem 1 and 3
      result = await test2.getVal(); // Problem 1 and 3
      assert(result.toNumber(), 30);
  })
})

欢迎堆栈溢出!

答案 1 :(得分:0)

我发现问题的原因。

@ Adam-Kipnis的关于文件生成的请求使我有了尝试启动另一个具有不同参数的专用网络的想法。 我从here带走了他们。 测试成功了!

不幸的是,我不记得我将那个创世纪文件存放在我的专用网络中的位置。 homesteadBlock,eip155Block,eip158Block,byzantiumBlock 中的值可能存在问题。 我将尝试部署剩余的合同并进行测试。我会写一些结果。

非常感谢大家的参与!您的报价对找到解决方案非常有用!