向 Solidity 结构添加一个新字段会使以太坊合约停止工作

Adding one new field to Solidity struct makes Ethereum Contract stop working

在以太坊私有网络 (geth) 中,我有非常简单的合约(在 Solidity 中)。

版本 1:

contract T {
   string log;
   function getLastLog() constant returns (string lastLog) { return log; }

   function T() { log = "[call end]: T()\n"; }

   struct TData {
      uint amount;
   }

   mapping (address => uint) balance;
   mapping (address => TData) mystructmap;

   function setBalance(address _user, uint _balance) {
       log = "[call start]: setBalance()\n";

       balance[_user] = _balance;
       mystructmap[_user] = TData({amount: 42});

       log = "[call end]: setBalance()\n";
   }

   function getBalance(address _user) constant returns (uint _balance) {
       return balance[_user];
   }
   function get42(address _user) constant returns (uint _fourtytwo) {
       return mystructmap[_user].amount;
   }
}

我确实部署了合约然后这样调用它(来自web3.js):

  1. contract.getLog()
  2. contract.setBalance(valid_address, 55)
  3. contract.getLog()
  4. contract.getBalance(地址)
  5. contract.get42(地址)

我得到的输出结果是:

  1. [通话结束]: T()
  2. [调用结束]: setBalance()
  3. 55
  4. 42

现在我只向 TData 结构添加一个新字段:

版本 2:

contract T {
   string log;
   function getLastLog() constant returns (string lastLog) { return log; }

   function T() { log = "[call end]: T()\n"; }

   struct TData {
      uint somedata;
      uint amount;
   }

   mapping (address => uint) balance;
   mapping (address => TData) mystructmap;

   function setBalance(address _user, uint _balance) {
       log = "[call start]: setBalance()\n";

       balance[_user] = _balance;
       mystructmap[_user] = TData({somedata: 11, amount: 42});

       log = "[call end]: setBalance()\n";
   }

   function getBalance(address _user) external constant returns (uint _balance) {
      return balance[_user];
   }
   function get42(address _user) external constant returns (uint _fourtytwo) {
      return mystructmap[_user].amount;
   }
}

我和上面一样调用:

  1. contract.getLog()
  2. contract.setBalance(valid_address, 55)
  3. contract.getLog()
  4. contract.getBalance(地址)
  5. contract.get42(地址)

但现在我得到:

  1. [通话结束]: T()
  2. [通话结束]: T()
  3. 0
  4. 0

似乎“setBalance()”函数未执行(或退出某处)并且存储中的状态未更改。

请帮忙!

谢谢。

我之前遇到过同样的问题。我很确定这与您根据请求发送的气体量有关。 Web3 会猜测,但这之前让我失败了。尝试根据您的请求手动发送不同数量的气体。

这是我正在做的事情:

store
.changeProduct(d.id, d.name, d.price, d.description, d.quantity,d.enabled, {from: account, gas:1000000})
  1. 任何操作的硬编码 Gas 都不是一个好主意。如果你这样做,你将不断陷入这种错误。你应该在启动方法之前检查 Gas
  2. 使用估算的 Gas API - https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethestimategas
  3. 当你使用 DApp public 时,你必须意识到矿工可以在 geth 控制台中调整 Gas 价格。

miner.setGasPrice(gasPrice);

希望对您有所帮助!