You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:48:09