2
votes

Faced a very not clear problem for me. There are two simple contracts:

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

The value of field Test1.val you can change as calling function setVal in Test1 contract and calling same function in Test2 (Of course after setting the address of the first contract in the second Test2.setTest1)).

In the Remix and tests (ganache) – everything works as expected. But on a Private Network (implemented via Geth) I have trouble: when I call Test2.setVal – the value is changed; when I call Test2.getVal – does not work. I make calls via web3j

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

In the point (1) there is an exception:

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

I have no idea what wrong with this. The mechanism of calling function from another contract is quite simple. But I can’t understand what I’m doing wrong.

And I tried to call contract’s functions throw geth-console. In this case there is no error, but simply Test2.getVal () returns 0.

I will be grateful for any ideas!

UPDATE. This is test (I used @Ferit's test)

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
The problem doesn’t appear to be in your contract. Do you get a valid TransactionReceipt returned from setVal().send()? Are you using the generated contract proxy?Adam Kipnis
Thanks for your reply. Yes, setVal().send() returned a valid TransactionReceipt. TransactionReceipt r = test2.setVal( BigInteger.valueOf(30)).send(); System.out.println( r.getBlockHash() ); result = test1.getVal().send(); System.out.println( "1) " + result ); result = test2.getVal().send(); // ERROR! System.out.println( "2) " + result ); Do you mean a proxy-java-class? Yes, I use web3j to generate it. For compilation I use truffle.vasiliy
Please add your genesis.json to the post and I’ll try deploying it when I have some time later tonight.Adam Kipnis
Thanks for your attention. Here is the genesis file: genesis_test.jsonvasiliy

2 Answers

0
votes

Problem 1: .send(). should be removed.

Problem 2: Are you sure that you passed the address of Test 1 instance to Test 2?

Problem 3: You need to call them asynchronously. In your test file, I don't see any async/await or any promise clauses.

Changes I made:

  • Moved the contracts to respective files (Test1.sol and Test2.sol).
  • Fixed problem 1 in the test file by deleting .send()
  • Fixed problem 2 in the test file by passing address of Test1 instance to Test2
  • Fixed problem 3 in the test file by using async/await syntax.

Fixed test file as follows:

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

Welcome to Stack Overflow!

0
votes

I thing I found the cause for the problem.

The request from @Adam-Kipnis’s about the file genesis gave me the idea to try to start another private network with different parameters. I took them from here. And the test has worked!

Unfortunately I don’t remember where I took that genesis file for my private network. There may be a problem with the values in homesteadBlock, eip155Block, eip158Block, byzantiumBlock. I will try to deploy my remaining contracts and test them. And I will write about results.

Great thanks you all for your participation! Your offers were very useful for finding a solution!