向Solidity struct添加一个新字段会使以太坊合同停止运行

时间:2016-02-24 11:28:41

标签: blockchain ethereum solidity smartcontracts

在以太坊私人网络(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. [call end]:T()
  2. [call end]: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. [call end]:T()
  2. [call end]:T()
  3. 0
  4. 0

似乎' setBalance()'函数未执行(或退出某处),存储状态不会改变。

请帮忙!

感谢。

2 个答案:

答案 0 :(得分:2)

我之前遇到过同样的问题。我非常确定它与你发送的气体量有关。 Web3会猜测,但此前我失败了。尝试手动发送不同数量的气体以及您的请求。

这是我正在做的事情:

store
.changeProduct(d.id, d.name, d.price, d.description, d.quantity,d.enabled, {from: account, gas:1000000})

答案 1 :(得分:0)

  1. 任何操作的硬编码气体都是一个坏主意。如果你这样做,你会不断遇到这种错误。在解雇方法之前,您应该检查气体
  2. 使用估算气体API - https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethestimategas
  3. 当您公开DApp时,您必须认识到矿工可以在geth控制台中调整燃气价格这一事实。
  4. miner.setGasPrice(gasPrice);

    希望有所帮助!