如何在Solidity中调用contract.transfer方法时调试运行时错误?
How can I debug the runtime error when call contract.transfer method in Solidity?
我已经从 Ganache 启动了一个私有网络,并使用 truffle 将我的合约部署到网络中。部署工作正常,我可以从合同中调用一些方法。但是当我尝试将以太币转移到另一个账户时出现错误。
我的合约代码是:
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.4;
pragma experimental ABIEncoderV2;
contract Ledger {
mapping(address => uint256) balances;
address payable owner;
event Transfered(address _from, address _to, uint256 amount);
constructor() {
owner = payable(msg.sender);
balances[tx.origin] = 10000;
}
function sendCoin(address payable receiver, uint256 amount)
payable public
returns (bool sufficient)
{
require(msg.sender == owner);
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver] += amount;
receiver.transfer(amount);
emit Transfered(msg.sender, receiver, amount);
return true;
}
function getBalance(address addr) public view returns (uint256) {
return balances[addr];
}
function getBalanceInCoin(address addr)
public
view
returns (uint256)
{
return convert(getBalance(addr), 100);
}
function convert(uint256 amount, uint256 conversionRate)
public
pure
returns (uint256 convertedAmount)
{
return amount * conversionRate;
}
}
当我 运行 它在 truffle
控制台中时:
truffle(development)> let ledger = await Ledger.deployed()
truffle(development)> let accounts = await web3.eth.getAccounts()
truffle(development)> (await ledger.sendCoin(accounts[1], 50))
Uncaught Error: Returned error: VM Exception while processing transaction: revert
at evalmachine.<anonymous>:1:17
at evalmachine.<anonymous>:2:49
at sigintHandlersWrap (vm.js:273:12)
at Script.runInContext (vm.js:142:14)
at runScript (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:364:1)
at Console.interpret (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:379:1)
at bound (domain.js:421:15)
at REPLServer.runBound [as eval] (domain.js:432:12)
at REPLServer.onLine (repl.js:909:10)
at REPLServer.emit (events.js:400:28)
at REPLServer.emit (domain.js:475:12)
at REPLServer.Interface._onLine (readline.js:434:10)
at REPLServer.Interface._line (readline.js:791:8)
at REPLServer.Interface._ttyWrite (readline.js:1136:14) {
data: {
'0xebf4283ab2e7ced42b27b67e8a25c73c7c29e26aa3c86a14c5d6bbaba2c5fc55': { error: 'revert', program_counter: 738, return: '0x' },
stack: 'RuntimeError: VM Exception while processing transaction: revert\n' +
' at Function.RuntimeError.fromResults (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/utils/runtimeerror.js:94:13)\n' +
' at BlockchainDouble.processBlock (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/blockchain_double.js:627:24)\n' +
' at runMicrotasks (<anonymous>)\n' +
' at processTicksAndRejections (internal/process/task_queues.js:93:5)',
name: 'RuntimeError'
},
hijackedStack: 'Error: Returned error: VM Exception while processing transaction: revert\n' +
' at Object.ErrorResponse (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/web3-core-helpers/lib/errors.js:28:1)\n' +
' at /Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/web3/node_modules/web3-core-requestmanager/lib/index.js:302:1\n' +
' at /Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/provider/wrapper.js:107:1\n' +
' at XMLHttpRequest.request.onreadystatechange (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/web3/node_modules/web3-providers-http/lib/index.js:98:1)\n' +
' at XMLHttpRequestEventTarget.dispatchEvent (/Users/joey/.nvm/versions/node/v14.18.0/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 (/Users/joey/.nvm/versions/node/v14.18.0/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 (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:318:1)\n' +
' at IncomingMessage.<anonymous> (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:289:47)\n' +
' at IncomingMessage.emit (events.js:412:35)\n' +
' at IncomingMessage.emit (domain.js:537:15)\n' +
' at endReadableNT (internal/streams/readable.js:1334:12)\n' +
' at processTicksAndRejections (internal/process/task_queues.js:82:21)'
如您所见,上述错误来自 sendCoin
方法中的 transfer
方法。我怎么知道错误来自什么以及我应该如何修复它?
我已经从 Ganache 启动了一个私有网络,并使用 truffle 将我的合约部署到网络中。部署工作正常,我可以从合同中调用一些方法。但是当我尝试将以太币转移到另一个账户时出现错误。
我的合约代码是:
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.4;
pragma experimental ABIEncoderV2;
contract Ledger {
mapping(address => uint256) balances;
address payable owner;
event Transfered(address _from, address _to, uint256 amount);
constructor() {
owner = payable(msg.sender);
balances[tx.origin] = 10000;
}
function sendCoin(address payable receiver, uint256 amount)
payable public
returns (bool sufficient)
{
require(msg.sender == owner);
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver] += amount;
receiver.transfer(amount);
emit Transfered(msg.sender, receiver, amount);
return true;
}
function getBalance(address addr) public view returns (uint256) {
return balances[addr];
}
function getBalanceInCoin(address addr)
public
view
returns (uint256)
{
return convert(getBalance(addr), 100);
}
function convert(uint256 amount, uint256 conversionRate)
public
pure
returns (uint256 convertedAmount)
{
return amount * conversionRate;
}
}
当我 运行 它在 truffle
控制台中时:
truffle(development)> let ledger = await Ledger.deployed()
truffle(development)> let accounts = await web3.eth.getAccounts()
truffle(development)> (await ledger.sendCoin(accounts[1], 50))
Uncaught Error: Returned error: VM Exception while processing transaction: revert
at evalmachine.<anonymous>:1:17
at evalmachine.<anonymous>:2:49
at sigintHandlersWrap (vm.js:273:12)
at Script.runInContext (vm.js:142:14)
at runScript (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:364:1)
at Console.interpret (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:379:1)
at bound (domain.js:421:15)
at REPLServer.runBound [as eval] (domain.js:432:12)
at REPLServer.onLine (repl.js:909:10)
at REPLServer.emit (events.js:400:28)
at REPLServer.emit (domain.js:475:12)
at REPLServer.Interface._onLine (readline.js:434:10)
at REPLServer.Interface._line (readline.js:791:8)
at REPLServer.Interface._ttyWrite (readline.js:1136:14) {
data: {
'0xebf4283ab2e7ced42b27b67e8a25c73c7c29e26aa3c86a14c5d6bbaba2c5fc55': { error: 'revert', program_counter: 738, return: '0x' },
stack: 'RuntimeError: VM Exception while processing transaction: revert\n' +
' at Function.RuntimeError.fromResults (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/utils/runtimeerror.js:94:13)\n' +
' at BlockchainDouble.processBlock (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/blockchain_double.js:627:24)\n' +
' at runMicrotasks (<anonymous>)\n' +
' at processTicksAndRejections (internal/process/task_queues.js:93:5)',
name: 'RuntimeError'
},
hijackedStack: 'Error: Returned error: VM Exception while processing transaction: revert\n' +
' at Object.ErrorResponse (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/web3-core-helpers/lib/errors.js:28:1)\n' +
' at /Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/web3/node_modules/web3-core-requestmanager/lib/index.js:302:1\n' +
' at /Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/provider/wrapper.js:107:1\n' +
' at XMLHttpRequest.request.onreadystatechange (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/web3/node_modules/web3-providers-http/lib/index.js:98:1)\n' +
' at XMLHttpRequestEventTarget.dispatchEvent (/Users/joey/.nvm/versions/node/v14.18.0/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 (/Users/joey/.nvm/versions/node/v14.18.0/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 (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:318:1)\n' +
' at IncomingMessage.<anonymous> (/Users/joey/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:289:47)\n' +
' at IncomingMessage.emit (events.js:412:35)\n' +
' at IncomingMessage.emit (domain.js:537:15)\n' +
' at endReadableNT (internal/streams/readable.js:1334:12)\n' +
' at processTicksAndRejections (internal/process/task_queues.js:82:21)'
如您所见,上述错误来自 sendCoin
方法中的 transfer
方法。我怎么知道错误来自什么以及我应该如何修复它?