Error: Returned error: VM Exception while processi

2019-08-22 02:37发布

问题:

I am trying to test a smart contract that monitors trading. I have three contracts, EscrowComplianceCecker, Industry, and Consumer. However, when testing my sendescrow() function on a truffle it seems to be throwing the above error. I am trying to figure out the reason for the bug

I debugged with the truffle debugger. The problem seems to be coming from the line
escrowobtainee.escrowobtainees[ escrowparticipator][obtcounter].escrowparticipantsinitialamountputin = escrowobtainee.escrowparticipantsinitialamountputin;

EscrowComplianceCecker.sol:

pragma solidity >=0.4.0 <0.6.0;

//^0.4.18;

contract EscrowComplianceCecker {
    uint public amountrequired = 2;
    address payable public escrowownaddress = 0xfd2C3e27BfACcf842424e48dC72cb18ba48E9457;

    uint escrowbalance = 0;
    uint value;
    uint m;
    mapping(uint256 => bool) usedNonces;

    struct EscrowSentBack{
        address payable escrowvictimaddress;
        bytes32 escrowvictimmame;
        uint escrowvictimmoney;
        bytes32 escrowvictimtimestamp;
        uint escrowvictimcount;

        mapping (address => EscrowSentBack[]) escrowteeser;
    }
    EscrowSentBack[] public punishings;
    struct EscrowObtained {
         address payable escrowparticipantaddress;
         bytes32 escrowparticipantname;
         uint escrowparticipantsinitialamountputin;
         bytes32 escrowparticipanttimestamp;
         uint escrowparticipantcount;

         mapping (address => EscrowObtained[]) escrowobtainees;
    } 
    EscrowObtained[] public proposals;

    EscrowObtained escrowobtainee;
    EscrowSentBack escrowtees;

    /*  constructor(uint  _amountrequired) public  {
        amountrequired = _amountrequired;
    }
    */
    // this is used by industry to send escrow to the EscrowComplianceCecker
    function sendescrow(address payable escrowparticipator, bytes32 escrowparticipatorname, uint escrowparticipatoramount) public {
 escrowobtainee.escrowobtainees;

    //  uint escrowedvaluesent;
    escrowobtainee.escrowparticipantcount;

   m = escrowobtainee.escrowparticipantcount;
   uint obtcounter = m++;

    escrowobtainee.escrowparticipantaddress= escrowparticipator;
    escrowobtainee.escrowparticipantname=escrowparticipatorname;
    escrowobtainee.escrowparticipantsinitialamountputin = escrowparticipatoramount;

    require(amountrequired <= escrowparticipatoramount, "This is not enough for escrow");

    //    escrowedvaluesent = escrowobtainee.escrowparticipantsinitialamountputin;
    escrowobtainee.escrowobtainees[  escrowparticipator][obtcounter].escrowparticipantsinitialamountputin =  escrowobtainee.escrowparticipantsinitialamountputin;   

    escrowbalance += escrowobtainee.escrowparticipantsinitialamountputin;
    proposals.push(EscrowComplianceCecker.EscrowObtained({
       escrowparticipantaddress: escrowobtainee.escrowobtainees[  escrowparticipator][obtcounter].escrowparticipantaddress,
      escrowparticipantname:escrowobtainee.escrowobtainees[ escrowparticipator][obtcounter].escrowparticipantname,
       escrowparticipantsinitialamountputin:escrowobtainee.escrowobtainees[  escrowparticipator][obtcounter].escrowparticipantsinitialamountputin,
      escrowparticipanttimestamp:escrowobtainee.escrowobtainees[  escrowparticipator][obtcounter].escrowparticipanttimestamp,
      escrowparticipantcount:escrowobtainee.escrowobtainees[ escrowparticipator][obtcounter].escrowparticipantcount
        // I HAVE TO ADD THE OTHER DETAILS
    }));  
}

//returns back the escrow
function returnbackescrow (address payable _escrowvictimaddress, bytes32 _escrowvictimmame, uint _escrowvictimmoney) public {
    escrowtees.escrowteeser;
    escrowobtainee.escrowobtainees;
    escrowobtainee.escrowparticipantaddress;
    //   uint      obtcounter;
    uint  obtanothercounter;

    require(escrowobtainee.escrowobtainees[ escrowobtainee.escrowparticipantaddress][obtanothercounter].escrowparticipantaddress == _escrowvictimaddress);

    m = escrowtees.escrowvictimcount;
    uint counter = m++;
    escrowtees.escrowvictimaddress = _escrowvictimaddress;
    escrowtees.escrowvictimmame =_escrowvictimmame;
    escrowtees.escrowvictimmoney =_escrowvictimmoney;

    escrowtees.escrowteeser[_escrowvictimaddress][counter].escrowvictimmoney = escrowobtainee.escrowobtainees[ escrowobtainee.escrowparticipantaddress][obtanothercounter].escrowparticipantsinitialamountputin;
     escrowtees.escrowteeser[_escrowvictimaddress][counter].escrowvictimaddress =escrowobtainee.escrowobtainees[ escrowobtainee.escrowparticipantaddress][obtanothercounter].escrowparticipantaddress; 

    uint mymoney = escrowtees.escrowteeser[_escrowvictimaddress][counter].escrowvictimmoney;
    address payable receipientaddress =  escrowtees.escrowteeser[_escrowvictimaddress][counter].escrowvictimaddress;
    require(msg.sender == escrowownaddress);
     escrowownaddress.transfer(mymoney);
     withdraw(mymoney,escrowbalance);
    emit Sent(escrowownaddress, receipientaddress, mymoney);

    // stores all the escrow kept

    punishings.push(EscrowComplianceCecker.EscrowSentBack({
      escrowvictimaddress: escrowtees.escrowteeser[_escrowvictimaddress][counter].escrowvictimaddress,
      escrowvictimmame:  escrowtees.escrowteeser[_escrowvictimaddress][counter].escrowvictimmame,
       escrowvictimmoney: escrowtees.escrowteeser[_escrowvictimaddress][counter].escrowvictimmoney,
      escrowvictimtimestamp: escrowtees.escrowteeser[_escrowvictimaddress][counter]. escrowvictimtimestamp,
      escrowvictimcount: escrowtees.escrowteeser[_escrowvictimaddress][counter].escrowvictimcount
       // I HAVE TO ADD THE OTHER DETAILS
    }));  
}

// industry worker can make deposit here
    function deposit(address payable donator, address payable receipient, uint amount) public payable {
        donator.transfer(amount);
        escrowbalance += amount;
        escrowownaddress = receipient;
    }

    function withdraw(uint balanceamount, uint escrowbalancenow) public payable {
        escrowbalance = escrowbalancenow;

        require(balanceamount <= escrowbalance, "Insufficient balance.");
        escrowbalance -= balanceamount; 
     }

     function balances() public view returns(uint) {
          return escrowbalance;   
     }

     event Sent(address payable from, address payable receipientaddress, uint amount);

    // THIS FUNCTION IS CALLED BY INDUSTRY; HE CLAIMS GOOD AFTER EXCHANGE;
    function claimPayment(uint256 amount, uint256 nonce, bytes memory signature,address payable receipientaddress)
    public {
        require(!usedNonces[nonce]);
        usedNonces[nonce] = true;
        // this recreates the message that was signed on the client
        bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this)));
        require(recoverSigner(message, signature) == escrowownaddress);
        msg.sender.transfer(amount);
        withdraw(amount,escrowbalance);
        emit Sent(msg.sender, receipientaddress, amount);
    }
    /// destroy the contract and reclaim the leftover funds.
    function kill() public {
    require(msg.sender == escrowownaddress);
    selfdestruct(msg.sender);
}

/// signature methods.
function splitSignature(bytes memory sig)
    internal
    pure
    returns (uint8 v, bytes32 r, bytes32 s)
    {
        require(sig.length == 65);
        assembly {
             // first 32 bytes, after the length prefix.
             r := mload(add(sig, 32))
             // second 32 bytes.
             s := mload(add(sig, 64))
             // final byte (first byte of the next 32 bytes).
             v := byte(0, mload(add(sig, 96)))
        }
        return (v, r, s);
    }

    // HERE IS WHERE RECOVER SIGNER IS PASSED TO HIM SO THAT HE CAN GET HIS MONEY
    function recoverSigner(bytes32 message, bytes memory sig)
    internal
    pure
    returns (address)
    {
        (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig);
        return ecrecover(message, v, r, s);
    }

    /// builds a prefixed hash to mimic the behavior of eth_sign.
    function prefixed(bytes32 hash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }
}

}

EscrowComplianceCecker.js for truffle test

const EscrowComplianceCecker = artifacts.require('EscrowComplianceCecker')

contract('EscrowComplianceCecker', (accounts) => {
    before(async () => {
        this.escrowComplianceCecker = await EscrowComplianceCecker.deployed()
    })

    it('deploys successfully', async () => {
        const address = await this.escrowComplianceCecker.amountrequired
        assert.notEqual(address, 0x0)
        assert.notEqual(address, '')
        assert.notEqual(address, null)
        assert.notEqual(address, undefined)
    })

    it('sends an escrow', async () => {
        let amountrequired = 4;
        const escrow = await this.escrowComplianceCecker.sendescrow(accounts[0], web3.utils.fromAscii("peeman"), amountrequired).then(function(result){
            assert.isAtLeast(amountrequired, 2,"Give me the assert here" );
        });
    }) 
})

When tested based on the values I gave it, it is expected to pass the test and give me the transaction details. Let's just say I am basically trying to test the smart contract