首页 > 解决方案 > 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 中设置第一个合约的地址之后)。

在混音和测试(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.

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

我试图调用合约的函数 throw 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);
  })
})

标签: solidity

解决方案


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

问题2:您确定将Test 1 实例的地址传递给Test 2 吗?

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

我所做的更改:

  • 将合约移至各自的文件(Test1.sol 和 Test2.sol)。
  • 通过删除修复了测试文件中的问题1.send()
  • 通过将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);
  })
})

欢迎来到堆栈溢出!


推荐阅读