Truffle框架下Solidity合约JS测试失败问题求助
问题分析与解决方案
先帮你拆解下核心问题,再给出针对性的修复方案:
1. 错误的核心原因:误用call()方法
你在测试里用了swindle.addPlayers.call("stuart"),但call()在Truffle中是只读调用——它只会模拟执行函数逻辑,不会把任何状态修改写入区块链。所以你的players数组根本没被添加元素,而且addPlayers函数本身没有返回值,导致then回调里拿到的swindle是undefined,这就触发了Cannot read property '0' of undefined的报错。
另外你的合约还有个隐藏坑:winner既是状态变量又是函数名,这在Solidity里会引发命名冲突,后续调用大概率出问题,建议把函数名改掉。
2. 修复后的测试代码
把call()改成直接调用函数(发送交易),再通过合约实例读取players数组:
var Swindle = artifacts.require("Swindle"); contract('Swindle', function(accounts) { it('sets player to stuart', function(){ let swindleInstance; return Swindle.deployed() .then(function(instance) { swindleInstance = instance; // 直接调用函数发送交易,不要用call() return swindleInstance.addPlayers("stuart", { from: accounts[0] }); }) .then(function() { // 读取players数组的第一个元素(Solidity数组要通过索引调用读取) return swindleInstance.players(0); }) .then(function(playerName) { assert.equal(playerName, "stuart", "Player stuart should be added to the array"); }); }); });
3. 合约代码优化建议
重命名冲突的winner函数,避免后续问题:
pragma solidity ^0.4.23; contract Swindle { string public eventName; uint public entryFee; string[] public players; string public winner; uint public winnings; function comp(string _eventName, uint _entryFee) public { eventName = _eventName; entryFee = _entryFee; } function addPlayers(string _player) public { players.push(_player); } // 把原winner函数重命名为setWinner,避免和状态变量冲突 function setWinner(string _player) public returns (string, uint) { winner = _player; winnings = (players.length * entryFee); return (winner, winnings); } }
这样修改后,测试就能正常执行,players数组也能正确读取到添加的元素了。
内容的提问来源于stack exchange,提问作者Falko
相关产品推荐
相关产品推荐

