向 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):
- contract.getLog()
- contract.setBalance(valid_address, 55)
- contract.getLog()
- contract.getBalance(地址)
- contract.get42(地址)
我得到的输出结果是:
- [通话结束]: T()
- [调用结束]: setBalance()
- 55
- 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;
}
}
我和上面一样调用:
- contract.getLog()
- contract.setBalance(valid_address, 55)
- contract.getLog()
- contract.getBalance(地址)
- contract.get42(地址)
但现在我得到:
- [通话结束]: T()
- [通话结束]: T()
- 0
- 0
似乎“setBalance()”函数未执行(或退出某处)并且存储中的状态未更改。
请帮忙!
谢谢。
我之前遇到过同样的问题。我很确定这与您根据请求发送的气体量有关。 Web3 会猜测,但这之前让我失败了。尝试根据您的请求手动发送不同数量的气体。
这是我正在做的事情:
store
.changeProduct(d.id, d.name, d.price, d.description, d.quantity,d.enabled, {from: account, gas:1000000})
- 任何操作的硬编码 Gas 都不是一个好主意。如果你这样做,你将不断陷入这种错误。你应该在启动方法之前检查 Gas
- 使用估算的 Gas API -
https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethestimategas
- 当你使用 DApp public 时,你必须意识到矿工可以在 geth 控制台中调整 Gas 价格。
miner.setGasPrice(gasPrice);
希望对您有所帮助!
在以太坊私有网络 (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):
- contract.getLog()
- contract.setBalance(valid_address, 55)
- contract.getLog()
- contract.getBalance(地址)
- contract.get42(地址)
我得到的输出结果是:
- [通话结束]: T()
- [调用结束]: setBalance()
- 55
- 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;
}
}
我和上面一样调用:
- contract.getLog()
- contract.setBalance(valid_address, 55)
- contract.getLog()
- contract.getBalance(地址)
- contract.get42(地址)
但现在我得到:
- [通话结束]: T()
- [通话结束]: T()
- 0
- 0
似乎“setBalance()”函数未执行(或退出某处)并且存储中的状态未更改。
请帮忙!
谢谢。
我之前遇到过同样的问题。我很确定这与您根据请求发送的气体量有关。 Web3 会猜测,但这之前让我失败了。尝试根据您的请求手动发送不同数量的气体。
这是我正在做的事情:
store
.changeProduct(d.id, d.name, d.price, d.description, d.quantity,d.enabled, {from: account, gas:1000000})
- 任何操作的硬编码 Gas 都不是一个好主意。如果你这样做,你将不断陷入这种错误。你应该在启动方法之前检查 Gas
- 使用估算的 Gas API - https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethestimategas
- 当你使用 DApp public 时,你必须意识到矿工可以在 geth 控制台中调整 Gas 价格。
miner.setGasPrice(gasPrice);
希望对您有所帮助!