Solidity

Truffle - 轉移導致“錯誤:處理事務時出現 VM 異常:還原”

  • October 24, 2018

作為參考,我正在使用 Solidity 為我的公司開發智能合約。我創建了一個智能合約並嘗試使用 Truffle 和 Ganache 對其進行單元測試。Error: VM Exception while processing transaction: revert但是,當我嘗試使用 Truffle 對其進行單元測試時,我的智能合約返回時遇到了一些問題。在對我的程式碼進行了大量測試後,我設法將智能合約縮減為以下程式碼,但仍然會產生錯誤。

pragma solidity ^0.4.22;

contract Purchase {

address public buyer;
address public seller;
address public companyEscrow;
uint private moneyInEscrow = 0;

modifier onlyCompanyEscrow {
   require(
       msg.sender == companyEscrow,
       "Only the escrow account of the company can call this function."
   );
   _;
}

modifier onlyBuyer {
   require(
       msg.sender == buyer,
       "Only the buyer can call this function."
   );
   _;
}

constructor (address addressSeller, address addressCompanyEscrow) public payable {
   buyer = msg.sender;
   seller = addressSeller;
   companyEscrow = addressCompanyEscrow;
}

function sendFundsToCompany ()
     public
     payable
     onlyBuyer
     returns (bool completed)
 {
     moneyInEscrow = msg.value;
     companyEscrow.transfer(moneyInEscrow);
     return true;
 }


 function sendFundsToSeller ()
     public
     payable
     onlyCompanyEscrow
     returns (bool completed)
 {
     seller.transfer(moneyInEscrow);
     moneyInEscrow = 0;
     return true;
 }
}

應該先執行函式 sendFundsToCompany(),然後再執行函式 sendFundsToSeller()。我將單元測試縮減為以下 Truffle 單元測試,但仍會產生錯誤:

var Web3Beta = require('web3')
var web3beta = new Web3Beta()
var Purchase = artifacts.require('Purchase')

contract('Purchase', function ([buyer, seller, companyEscrow] {

 var purchase = await Purchase.new(seller, companyEscrow)

 it('Should send funds to seller', async function () {
   var sellerInitialBalance = web3.eth.getBalance(seller).toNumber()
   var companyEscrowInitialBalance = web3.eth.getBalance(companyEscrow).toNumber()

   await purchase.sendFundsToCompany({ value: web3beta.utils.toWei('3', 'ether'), gas: "6600000" })
   await purchase.sendFundsToSeller({ from: companyEscrow, gas: "6600000" })

   assert.isAbove(web3.eth.getBalance(seller).toNumber(), sellerInitialBalance)
   assert.isBelow(web3.eth.getBalance(companyEscrow).toNumber(), companyEscrowInitialBalance)
 })
})

我梳理了 Ethereum StackExchange、Truffle 幫助板和 Solidity 文件。但是,該錯誤仍然使我難以捉摸。在查看了乙太坊 StackExchange 上的類似問題後,我執行了以下操作:

  • 我確保這兩個函式都有“payable”修飾符。
  • 我明確地向函式發送了一個大的氣體限制。
  • 我刪除了 /builds 文件夾並重新編譯了所有內容。
  • 我結束了目前部署並使用“truffle develop”啟動了一個新實例。

不幸的是,做這些事情並沒有解決我的問題。我對問題所在有點茫然。我是 Solidity 的新手,所以它可能是一些基本的東西;但是,我似乎無法弄清楚它是什麼。

作為參考,我的 Truffle 版本是 4.1.13,我的 Ganache 版本是 6.1.6(ganache-core = 2.1.5)。此外,我正在執行“松露開發”並在兩個單獨的命令提示符中執行單元測試 - 我在一個提示符中執行“松露開發”,然後才在另一個命令提示符中執行單元測試。

我將不勝感激您能為我提供的任何幫助或指導。先感謝您!

可能還有其他問題,但這肯定是一個:

function sendFundsToCompany ()
   public
   payable
   onlyBuyer
   returns (bool completed)
{
   moneyInEscrow = msg.value;
   companyEscrow.transfer(moneyInEscrow);
   return true;
}

如果你向這個函式發送 1 wei,那麼moneyInEscrow == 1,那 1 wei 被轉移到companyEscrow。所以合約餘額保持在0。

function sendFundsToSeller ()
   public
   payable
   onlyCompanyEscrow
   returns (bool completed)
{
   seller.transfer(moneyInEscrow);
   moneyInEscrow = 0;
   return true;
}

如果您隨後呼叫此函式,則會嘗試將moneyInEscrow(1) wei 發送到seller。但是合約餘額為0,所以這次轉賬會失敗。

引用自:https://ethereum.stackexchange.com/questions/53273