solidity的一段代码revert
使用ganache和truffle开发,使用了如下两个合约,首先部署Game合约,然后部署GamePlayer。在执行GamePlayer的attack时,运行到g.deposit{value:1}();就会被revert,麻烦各位大神赐教。代码和truffle console的运行命令如下
代码:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract Game{
//记录各个玩家余额
mapping(address => uint256) private balance;
constructor() payable {
}
//玩家下注函数,向游戏合约充值
function deposit() public payable{
balance[msg.sender] += msg.value;
}
//玩家向其他玩家转移游戏合约中的资产
function playerTransfer(address to, uint amount) public {
require(balance[msg.sender] >= amount);
balance[to] += amount;
balance[msg.sender] -= amount;
}
//玩家提款函数
function withdraw() public {
bool ret;
bytes memory data;
uint256 amount = balance[msg.sender];
(ret, data) = msg.sender.call{value:amount}("");
if (ret){
balance[msg.sender] = 0;
}
}
//查询游戏合约中玩家的资产
function playerBalance(address player) public view returns(uint256){
return balance[player];
}
//获取合约总余额函数
function gameBalance() public view returns(uint256){
return address(this).balance;
}
}
contract GamePlayer{
//记录游戏合约地址
address payable target;
//记录攻击者外部账户地址
address attacker;
constructor() payable{
}
//攻击函数,外部账户调用这个合约对游戏合约进行攻击
function attack(address payable addr) public{
//记录被攻击者合约地址和攻击者外部账户地址
target = addr;
attacker = (msg.sender);
Game g = Game(target);
//攻击合约做为玩家向游戏中充值一个1以太币
g.deposit{value:1}();
//提款
//g.withdraw();
}
//fallback函数
fallback() payable external {
// Game g = Game(target);
// 将游戏合约中的1个以太币转移给攻击者外部账户
// g.playerTransfer(attacker, 1000);
}
}
truffle console执行的命令:
let accounts = await web3.eth.getAccounts()
let gameInstance = await Game.new()
gameInstance.deposit({from:accounts[0], value:100000})
let gamePlayerInstance = await GamePlayer.new()
gamePlayerInstance.attack(gameInstance.address)
报错信息:
Uncaught Error: Returned error: VM Exception while processing transaction: revert
at evalmachine.<anonymous>:1:28
at evalmachine.<anonymous>:2:49
at sigintHandlersWrap (vm.js:274:12)
at Script.runInContext (vm.js:142:14)
at runScript (/opt/node-v14.17.1-linux-x64/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:329:1)
at Console.interpret (/opt/node-v14.17.1-linux-x64/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:344:1)
at bound (domain.js:416:15)
at REPLServer.runBound [as eval] (domain.js:427:12)
at REPLServer.onLine (repl.js:819:10)
at REPLServer.emit (events.js:375:28)
at REPLServer.emit (domain.js:470:12)
at REPLServer.Interface._onLine (readline.js:364:10)
at REPLServer.Interface._line (readline.js:700:8)
at REPLServer.Interface._ttyWrite (readline.js:1045:14) {
data: {
'0x259e0a165fb8dd25fec6ee83b184d9b3c32dccf251a7aa58aa4ce5da7fad3c6e': { error: 'revert', program_counter: 344, return: '0x' },
stack: 'c: VM Exception while processing transaction: revert\n' +
' at Function.c.fromResults (/opt/node-v14.17.1-linux-x64/lib/node_modules/ganache-cli/build/ganache-core.node.cli.js:4:192416)\n' +
' at w.processBlock (/opt/node-v14.17.1-linux-x64/lib/node_modules/ganache-cli/build/ganache-core.node.cli.js:42:50915)\n' +
' at runMicrotasks (<anonymous>)\n' +
' at processTicksAndRejections (internal/process/task_queues.js:95:5)',
name: 'c'
},
hijackedStack: 'Error: Returned error: VM Exception while processing transaction: revert\n' +
' at Object.ErrorResponse (/opt/node-v14.17.1-linux-x64/lib/node_modules/truffle/build/webpack:/node_modules/web3-core-helpers/lib/errors.js:28:1)\n' +
' at /opt/node-v14.17.1-linux-x64/lib/node_modules/truffle/build/webpack:/node_modules/web3/node_modules/web3-core-requestmanager/lib/index.js:303:1\n' +
' at /opt/node-v14.17.1-linux-x64/lib/node_modules/truffle/build/webpack:/packages/provider/wrapper.js:107:1\n' +
' at XMLHttpRequest.request.onreadystatechange (/opt/node-v14.17.1-linux-x64/lib/node_modules/truffle/build/webpack:/node_modules/web3/node_modules/web3-providers-http/lib/index.js:98:1)\n' +
' at XMLHttpRequestEventTarget.dispatchEvent (/opt/node-v14.17.1-linux-x64/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:1)\n' +
' at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._setReadyState (/opt/node-v14.17.1-linux-x64/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:208:1)\n' +
' at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._onHttpResponseEnd (/opt/node-v14.17.1-linux-x64/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:318:1)\n' +
' at IncomingMessage.<anonymous> (/opt/node-v14.17.1-linux-x64/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:289:47)\n' +
' at IncomingMessage.emit (events.js:387:35)\n' +
' at IncomingMessage.emit (domain.js:532:15)\n' +
' at endReadableNT (internal/streams/readable.js:1317:12)\n' +
' at processTicksAndRejections (internal/process/task_queues.js:82:21)'
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通过其他实验发现,这里revert的原因应该是余额不足。实验发现在attack方法中调用deposit的话,对于Game这个合约来说msg.sender其实是GamePlayer的合约地址。但是之前一直没有对GamePlayer合约进行充值,所以GamePlayer的balance就是0,最终导致revert调用失败。解决方法就是在GamePlayer创建的时候先充入一些以太。