solidity - 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);
})
})
解决方案
问题.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);
})
})
欢迎来到堆栈溢出!
推荐阅读
- session - 控制台中的 Dialogflow 更新上下文
- javascript - 如何使用 PIXI.Graphics 在 PIXI.js 中绘制可点击的线条?
- nginx - 对 kubernetes 上的入口进行故障排除
- java - 将 Java final 关键字添加到在循环内构建实例的工作方法
- reactjs - 无法在酶测试中设置上下文
- python - sklearn线性模型中Copy_X是什么意思
- python - 为逻辑谜题建模
- php - wordpress,avada 主题,白屏
- c# - 如何在线程在计时器中休眠之前输出文本?
- android - 找不到参数 [com.google.gms:google-services:4.0.0] 的方法 compile()