我有2个基本合同:一个是令牌,第二个是出售。
令牌ê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 和 Ownable 都是OpenZeppelin存储库的标准实现。完整的合同来源here。
所以基本上在我的销售合同中,我创建了一个具有固定供应的令牌合同实例,并将所有令牌分配给调用者。然后我将一些令牌转移到创始人地址。当我尝试向销售合同发送一些以太坊时,我试图将我的一些令牌转移到发件人(在Remix浏览器中运行所有代码,我创建一个Sale合约的实例并调用“fallback”方法指定一些以太量)。但是,这会导致“执行期间出现异常。(操作码无效)。请调试事务以获取更多信息。”信息。我在调试时看到的所有内容都是代码在应付方法中失败:
token.transfer(msg.sender, 1);
我无法确切地看到这个的确切原因,因为我无法进入这种方法并看到内部发生了什么。
有趣的是,当我在Sale Contract构造函数中删除对令牌实例上的传输方法的调用时 - 代码似乎运行正常,没有任何例外。
我错过了什么?
答案 0 :(得分:0)
我使用remix调试合同,无效的操作码被抛出:
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.此时,我不确定这是混音中的限制还是我误解了设置。
我在truffle + testrpc上尝试了相同的合同设置并进行了部署,成功接受了货币。请注意,testrpc指出:
Gas usage: 59137
这意味着它高于默认的sendTransaction w / no data default(21,000 gas)。这意味着在实时环境中,请确保通知用户包含额外的气体,否则由于OOG错误,后备功能可能会失败。
答案 1 :(得分:0)
这背后的原因是您正在使用回退功能。尝试使用正常功能,它应该会发生。