在另一个合同内创建合同实例并调用它的方法会导致抛出的异常
问题描述:
我有两个基本合同:一个用于令牌,第二个用于销售。在另一个合同内创建合同实例并调用它的方法会导致抛出的异常
令牌сontract:
contract MyToken is StandardToken, Ownable {
string public constant name = "My Sample Token";
string public constant symbol = "MST";
uint32 public constant decimals = 18;
function MyToken(uint _totalSupply) {
require (_totalSupply > 0);
totalSupply = _totalSupply;
balances[msg.sender] = totalSupply;
}
}
买卖合同
contract Sale {
address owner;
address public founderAddress;
uint256 public constant foundersAmount = 50;
MyToken public token = new MyToken(1000);
uint256 public issuedTokensAmount = 0;
function Sale() {
owner = msg.sender;
founderAddress = 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c;
token.transfer(founderAddress, foundersAmount);
}
function() external payable {
token.transfer(msg.sender, 1);
owner.transfer(msg.value);
}
}
StandardToken和可拥有从OpenZeppelin库中的所有标准实现。完整合同来源可用here。
因此,基本上在我的销售合同中,我创建了具有固定供应的令牌合同实例,并将所有令牌分配给调用方。然后我将一些令牌转移到创始人地址。当我尝试向销售合同发送一些以太币时,我试图将一些令牌转移给发件人(在Remix浏览器中运行所有代码,创建销售合同的实例并调用指定一些以太量的“回退”方法)。但是,这会因“执行期间的异常(无效的操作码)而失败,请调试交易以获取更多信息。”信息。所有调试时,我可以看到的是,在代码的应付税款法在线路出现故障:
token.transfer(msg.sender, 1);
我看不到这种情况的确切原因是我不能够踏进这个方法,看看怎么回事内。
有趣的是,当我在销售合同构造函数中删除调用令牌实例上的调用方法时,代码似乎运行良好,没有任何例外。
我错过了什么?
答
我调试到合同利用混音,以及无效的操作码被抛出:
290 DUP8
291 DUP1
292 EXTCODESIZE
293 ISZERO
294 ISZERO
295 PUSH2 012f
298 JUMPI
299 PUSH1 00
301 DUP1
302 INVALID
我离开了休息,但实际上它加载令牌合同的地址和电话EXTCODESIZE以检索合同代码大小,并检查它不等于0(令牌合约存在),不幸的是,它确实等于0.此时,我不确定这是混音的限制还是我误解了设置。
我尝试了与松露+ testrpc相同的合同设置,并部署了它,并成功接受了货币。不要但是请注意testrpc表示:
Gas usage: 59137
含义,这是上面默认sendTransaction瓦特/没有数据的默认(21000种气体)。这意味着在实时环境中,请确保通知用户包含额外的气体,否则后备功能可能会由于OOG错误而失败。