We are modifying the code used in a blockchain class to develop our first Dapp. We have added more variables to the contract code, and when we run the test files, we get the following errors:
"Invalid number of arguments to Solidity function" (Tests 1 & 2)
"VM exception while processing transaction: revert" (Test 3)
How can we correct this? Are there steps that we missed in deploying the contract?
Is this the reason why Metamask will not process the transaction? Any guidance will help. Thanks!
Here is the contract code:
pragma solidity ^0.4.18;
import "./Ownable.sol";
contract OurRentalTestFromClassMay24 is Ownable {
struct Article{
uint id;
address seller;
address buyer;
uint beds;
uint baths;
string propaddress;
uint rental_price;
string article_description;
string available;
string contact_email;
}
mapping(uint => Article) public articles;
uint articleCounter;
event LogSellArticle(
address indexed _seller,
uint _beds,
uint _baths,
string _propaddress,
uint _rental_price,
string _article_description,
string _available,
string _contact_email
);
event LogBuyArticle(
uint indexed _id,
address indexed _seller,
address indexed _buyer,
uint _beds,
uint _baths,
string _propaddress,
uint _rental_price,
string _article_description,
string _available,
string _contact_email
);
function kill() public onlyOwner {
selfdestruct(owner);
}
function sellArticle(uint _beds, uint _baths, string _propaddress, uint _rental_price, string _article_description, string _available, string _contact_email) public {
articleCounter++;
articles[articleCounter] = Article(
articleCounter,
msg.sender,
0x0,
_beds,
_baths,
_propaddress,
_rental_price,
_article_description,
_available,
_contact_email
);
LogSellArticle(msg.sender, _beds, _baths, _propaddress, _rental_price, _article_description, _available, _contact_email);
}
function getNumberOfArticles() public view returns (uint){
return articleCounter;
}
function getArticlesForSale() public view returns (uint[]){
uint[] memory articleIds = new uint[](articleCounter);
uint numberOfArticlesForSale = 0;
for(uint i = 1; i <= articleCounter; i++){
if(articles[i].buyer == 0x0){
articleIds[numberOfArticlesForSale] = articles[i].id;
numberOfArticlesForSale++;
}
}
uint[] memory forSale = new uint[](numberOfArticlesForSale);
for(uint j = 0; j < numberOfArticlesForSale; j++){
forSale[j] = articleIds[j];
}
return forSale;
}
function buyArticle(uint _id) payable public {
require(articleCounter > 0);
require(_id > 0 && _id <= articleCounter);
Article storage article = articles[_id];
require(article.buyer == 0x0);
require(msg.sender != article.seller);
require(msg.value == article.rental_price);
article.buyer = msg.sender;
article.seller.transfer(msg.value);
LogBuyArticle(_id, article.seller, article.buyer, article.beds, article.baths, article.propaddress, article.rental_price, article.article_description, article.available, article.contact_email);
}
}
Here is the test code:
var Rental =artifacts.require("./OurRentalTestFromClassMay24.sol");
contract('Rental', function(accounts){
var chainListInstance;
var seller = accounts[1];
var buyer = accounts[2];
var beds = "beds";
var baths = "baths";
var propaddress = "propaddress";
var rental_price = "rental_price";
var article_description = "article_description";
var available = "available";
var contact_email = "contact_email";
var beds2 = "beds2";
var baths2 = "baths2";
var propaddress2 = "propaddress2";
var rental_price2 = "rental_price2";
var article_description2 = "article_description2";
var available2 = "available2";
var contact_email2 = "contact_email2";
var articleName1 = "article 1";
var articleDescription1 ="Description for article 1";
var articlePrice1 = 10;
var articleName2 = "article 2";
var articleDescription2 = "Description for article 2";
var articlePrice2 = 20;
var sellerBalanceBeforeBuy, sellerBalanceAfterBuy;
var buyerBalanceBeforeBuy, buyerBalanceAfterBuy;
it("should be initialized with empty values", function(){
return Rental.deployed().then(function(instance){
chainListInstance = instance;
return chainListInstance.getNumberOfArticles();
}).then(function(data){
assert.equal(data.toNumber(), 0, "number of articles must be zero");
return chainListInstance.getArticlesForSale();
}).then(function(data){
assert.equal(data.length, 0, "there shouldn't be any articles for sale");
});
});
it("should let us sell first article", function(){
return Rental.deployed().then(function(instance){
chainListInstance = instance;
return chainListInstance.sellArticle(
beds,
baths,
propaddress,
rental_price,
article_description,
available,
contact_email,
articleName1,
articleDescription1,
web3.toWei(articlePrice1, "ether"),
{from: seller}
);
}).then(function(receipt){
assert.equal(receipt.logs.length, 1, "one event should have been triggered");
assert.equal(receipt.logs[0].event, "LogSellArticle", "event should be LogSellArticle");
assert.equal(receipt.logs[0].args._id.toNumber(), 1, "id must be 1");
assert.equal(receipt.logs[0].args._seller, seller, "event seller must be " + seller);
assert.equal(receipt.logs[0].args._name, articleName1, "event article name must be " + articleName1);
assert.equal(receipt.logs[0].args._name, beds, "event beds must be " + beds);
assert.equal(receipt.logs[0].args._name, baths, "event baths must be " + baths);
assert.equal(receipt.logs[0].args._name, propaddress, "event propaddress must be " + propaddress);
assert.equal(receipt.logs[0].args._name, rental_price, "event rental_price must be " + rental_price);
assert.equal(receipt.logs[0].args._name, article_description, "event article_description must be " + article_description);
assert.equal(receipt.logs[0].args._name, available, "event available must be " + available);
assert.equal(receipt.logs[0].args._name, contact_email, "event contact_email must be " + contact_email);
assert.equal(receipt.logs[0].args._price.toNumber(), web3.toWei(articlePrice1, "ether"), "event article price must be " + web3.toWei(articlePrice1, "ether"));
return chainListInstance.getNumberOfArticles();
}).then(function(data){
assert.equal(data, 1, "number of articles must be one");
return chainListInstance.getArticlesForSale();
}).then(function(data) {
assert.equal(data.length, 1, "there must be one article for sale");
assert.equal(data[0].toNumber(), 1, "article id must be 1");
return chainListInstance.articles(data[0]);
}).then(function(data){
assert.equal(data[0].toNumber(), 1, "article id must be 1");
assert.equal(data[1], seller, "seller must be " + seller);
assert.equal(data[2], 0x0, "buyer must be empty");
assert.equal(data[3], articleName1, "article name must be " + articleName1);
assert.equal(data[4], articleDescription1, "article description must be " + articleDescription1);
assert.equal(data[5].toNumber(), web3.toWei(articlePrice1, "ether"), "article price must be " + web3.toWei(articlePrice1, "ether"));
assert.equal(data[6], beds, "beds must be " + beds);
assert.equal(data[7], baths, "baths must be " + baths);
assert.equal(data[8], propaddress, "propaddress must be " + propaddress);
assert.equal(data[9], rental_price, "rental_price must be " + rental_price);
assert.equal(data[10], article_description, "article_description must be " + article_description);
assert.equal(data[11], available, "available must be " + available);
assert.equal(data[12], contact_email, "contact_email must be " + contact_email);
});
});
it("should let us sell second article", function(){
return Rental.deployed().then(function(instance){
chainListInstance = instance;
return chainListInstance.sellArticle(
beds2,
baths2,
propaddress2,
rental_price2,
article_description2,
available2,
contact_email2,
articleName2,
articleDescription2,
web3.toWei(articlePrice2, "ether"),
{from: seller}
);
}).then(function(receipt){
assert.equal(receipt.logs.length, 1, "one event should have been triggered");
assert.equal(receipt.logs[0].event, "LogSellArticle", "event should be LogSellArticle");
assert.equal(receipt.logs[0].args._id.toNumber(), 2, "id must be 2");
assert.equal(receipt.logs[0].args._seller, seller, "event seller must be " + seller);
assert.equal(receipt.logs[0].args._name, beds2, "event beds must be " + beds2);
assert.equal(receipt.logs[0].args._name, baths2, "event baths must be " + baths2);
assert.equal(receipt.logs[0].args._name, propaddress2, "event propaddress must be " + propaddress2);
assert.equal(receipt.logs[0].args._name, rental_price2, "event rental_price must be " + rental_price2);
assert.equal(receipt.logs[0].args._name, article_description2, "event article_description must be " + article_description2);
assert.equal(receipt.logs[0].args._name, available2, "event available must be " + available2);
assert.equal(receipt.logs[0].args._name, contact_email2, "event contact_email must be " + contact_email2);
assert.equal(receipt.logs[0].args._name, articleName2, "event article name must be " + articleName2);
assert.equal(receipt.logs[0].args._price.toNumber(), web3.toWei(articlePrice2, "ether"), "event article price must be " + web3.toWei(articlePrice2, "ether"));
return chainListInstance.getNumberOfArticles();
}).then(function(data){
assert.equal(data, 2, "number of articles must be two");
return chainListInstance.getArticlesForSale();
}).then(function(data) {
assert.equal(data.length, 2, "there must be two articles for sale");
assert.equal(data[1].toNumber(), 2, "article id must be 2");
return chainListInstance.articles(data[1]);
}).then(function(data){
assert.equal(data[0].toNumber(), 2, "article id must be 2");
assert.equal(data[1], seller, "seller must be " + seller);
assert.equal(data[2], 0x0, "buyer must be empty");
assert.equal(data[3], articleName2, "article name must be " + articleName2);
assert.equal(data[4], articleDescription2, "article description must be " + articleDescription2);
assert.equal(data[5].toNumber(), web3.toWei(articlePrice2, "ether"), "article price must be " + web3.toWei(articlePrice2, "ether"));
assert.equal(data[6], beds2, "beds must be " + beds2);
assert.equal(data[7], baths2, "baths must be " + baths2);
assert.equal(data[8], propaddress2, "propaddress must be " + propaddress2);
assert.equal(data[9], rental_price2, "rental_price must be " + rental_price2);
assert.equal(data[10], article_description2, "article_description must be " + article_description2);
assert.equal(data[11], available2, "available must be " + available2);
assert.equal(data[12], contact_email2, "contact_email must be " + contact_email2);
});
});
it("should buy an article", function (){
return Rental.deployed().then(function(instance){
chainListInstance = instance;
sellerBalanceBeforeBuy = web3.fromWei(web3.eth.getBalance(seller), "ether").toNumber();
buyerBalanceBeforeBuy = web3.fromWei(web3.eth.getBalance(buyer), "ether").toNumber();
return chainListInstance.buyArticle(1, {
from: buyer,
value: web3.toWei(articlePrice1, "ether")
});
}).then(function(receipt){
assert.equal(receipt.logs.length, 1, "one event should have been triggered");
assert.equal(receipt.logs[0].event, "LogBuyArticle", "event should be LogBuyArticle");
assert.equal(receipt.logs[0].args._id.toNumber(), 1,"article id must be 1");
assert.equal(receipt.logs[0].args._seller, seller, "event seller must be " + seller);
assert.equal(receipt.logs[0].args._buyer, buyer, "event buyer must be " + buyer);
assert.equal(receipt.logs[0].args._name, articleName1, "event article name must be " + articleName1);
assert.equal(receipt.logs[0].args._name, beds, "event beds must be " + beds);
assert.equal(receipt.logs[0].args._name, baths, "event baths must be " + baths);
assert.equal(receipt.logs[0].args._name, propaddress, "event propaddress must be " + propaddress);
assert.equal(receipt.logs[0].args._name, rental_price, "event rental_price must be " + rental_price);
assert.equal(receipt.logs[0].args._name, article_description, "event article_description must be " + article_description);
assert.equal(receipt.logs[0].args._name, available, "event available must be " + available);
assert.equal(receipt.logs[0].args._name, contact_email, "event contact_email must be " + contact_email);
assert.equal(receipt.logs[0].args._price.toNumber(),web3.toWei(articlePrice1, "ether"), "event article price must be " + web3.toWei(articlePrice1, "ether"));
sellerBalanceAfterBuy = web3.fromWei(web3.eth.getBalance(seller), "ether").toNumber();
buyerBalanceAfterBuy = web3.fromWei(web3.eth.getBalance(buyer), "ether").toNumber();
assert(sellerBalanceAfterBuy == sellerBalanceBeforeBuy + articlePrice1, "seller should have earned " + articlePrice1 + " ETH");
assert(buyerBalanceAfterBuy <= buyerBalanceBeforeBuy - articlePrice1, "buyer should have spent " + articlePrice1 + " ETH");
return chainListInstance.getArticlesForSale();
}).then(function(data){
assert.equal(data.length, 1, "there should now be only 1 article left for sale");
assert.equal(data[0].toNumber(), 2, "article 2 should be the only article for sale");
return chainListInstance.getNumberOfArticles();
}).then(function(data){
assert.equal(data.toNumber(), 2, "there should still be 2 articles in total");
});
});
});
These are the errors we are getting:
Contract: Rental
√ should be initialized with empty values (135ms)
1) should let us sell first article
> No events were emitted
2) should let us sell second article
> No events were emitted
3) should buy an article
> No events were emitted
1 passing (2s)
3 failing
1) Contract: Rental should let us sell first article:
Error: Invalid number of arguments to Solidity function
at Object.InvalidNumberOfSolidityArgs (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\errors.js:25:1)
at SolidityFunction.validateArgs (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\function.js:74:1)
at SolidityFunction.toPayload (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\function.js:90:1)
at SolidityFunction.sendTransaction (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\function.js:163:1)
at SolidityFunction.execute (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\function.js:256:1)
at C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\truffle-contract\contract.js:204:1
at new Promise (<anonymous>)
at C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\truffle-contract\contract.js:155:1
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:160:7)
2) Contract: Rental should let us sell second article:
Error: Invalid number of arguments to Solidity function
at Object.InvalidNumberOfSolidityArgs (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\errors.js:25:1)
at SolidityFunction.validateArgs (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\function.js:74:1)
at SolidityFunction.toPayload (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\function.js:90:1)
at SolidityFunction.sendTransaction (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\function.js:163:1)
at SolidityFunction.execute (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\function.js:256:1)
at C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\truffle-contract\contract.js:204:1
at new Promise (<anonymous>)
at C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\truffle-contract\contract.js:155:1
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:160:7)
3) Contract: Rental should buy an article:
Error: VM Exception while processing transaction: revert
at Object.InvalidResponse (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\errors.js:38:1)
at C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\requestmanager.js:86:1
at C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\truffle-provider\wrapper.js:134:1
at XMLHttpRequest.request.onreadystatechange (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\httpprovider.js:128:1)
at XMLHttpRequestEventTarget.dispatchEvent (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:64:1)
at XMLHttpRequest._setReadyState (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:354:1)
at XMLHttpRequest._onHttpResponseEnd (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:509:1)
at IncomingMessage.<anonymous> (C:\Users\User\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:469:1) at endReadableNT (_stream_readable.js:1101:12)
truffle debug
? – James_pic May 31 '18 at 22:33