首先,我是新手,所以请耐心等待。我创建了一个包含HTML前端和Javascript文件的合约。合同编译正确,但是当我尝试发布一个项目(调用sellArticle函数)时,我得到错误“Solidity中的参数数量无效”我似乎找不到这个解决方案,所以我真的很感激任何帮助。谢谢。 我已经发布了以下代码。
INDEX.HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Rent My Place</title>
<!-- Title will appear as a tab in browser on webpage -->
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- Application -->
<link href="css/app.css" rel="stylesheet">
<!-- stylesheet refers to the look of the page, Font, color-->
</head>
<body>
<div class="container">
<!-- container that contains title panel-->
<div class="jumbotron text-center">
<p style="font-size:80px;padding: 1em;padding-top: 10px;padding-bottom: 10px; border:10px;border-style:solid;border-color:#c3c3c3;">
<font color = "#880015" >Rent My Place</font></p>
</div>
<div class="col-md-12" id="article-list">
<div class="row">
<div class="col-lg-12">
<p id="account" class="welcome pull-right"></p>
<p id="accountBalance" class="welcome pull-left"></p>
</div>
</div>
<div class="row panel panel-default">
<div class="panel-heading clearfix">
<div class="panel-title">
<p style="font-size:24px;padding: 1em;padding-top: 10px;padding-bottom: 10px; border:5px;border-style:solid;border-color:#c3c3c3;">
<font color = "#880015">Renter's Tip: </font><font color = "#000000">Inspect the property before you send money.</font><br><font color = "#880015">Landlord's Tip: </font><font color = "#000000">Meet prospective tenants in person.</font></p>
<!-- Button that opens second window to a form to fill out-->
<button class="btn btn-info btn-lg pull-right" data-toggle="modal" data-target="#sellArticle">Post a Rental</button>
</div>
</div>
<!-- when the event button gets click, it will show the list-->
<ul id="events" class="collapse list-group"></ul>
</div>
<div id="articlesRow" class="row">
<!-- ARTICLES with pertinent item information LOAD HERE -->
</div>
</div>
</div>
<!--Result that is displayed after input-->
<div id="articleTemplate" style="display: none;">
<div class="row-lg-12">
<div class="panel panel-default panel-article">
<div class="panel-heading">
<h3 class="panel-title"></h3>
</div>
<div class="panel-body">
<strong>Beds</strong>: <span class="beds"></span><br/>
<strong>Baths</strong>: <span class="baths"></span><br/>
<strong>Address</strong>: <span class="propaddress"></span><br/>
<strong>Rental Price</strong>: <span class="rental_price"></span><br/>
<strong>Property Type</strong>: <span class="property_type"></span><br/>
<strong>Description</strong>: <span class="description"></span><br/>
<strong>Property is available for showing</strong>: <span class="available"></span><br/>
<strong>Contact Email</strong>: <span class="contact_email"></span><br/>
<!--<strong>Sold by</strong>: <span class="article-seller"></span><br/>-->
</div>
<div class="panel-footer">
<button type="button" class= "btn btn-primary btn-success btn-buy" onclick="App.buyArticle(); return false;">Buy</button>
</div>
</div>
</div>
</div>
<!-- Modal form to sell an article -->
<div class="modal fade" id="sellArticle" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Rent Your Place</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-lg-12">
<form>
<div class="form-group">
<!--NOTE: For radio buttons to work, 'name' field must match-->
<label for="property_type">Property Type</label>
<input type="radio" name="property" id="house" value="house" > House
<input type="radio" name="property" id="apartment" value="apartment" > Apartment
<input type="radio" name="property" id="duplex" value="duplex" > Duplex
</div>
<div class="form-group">
<label for="propaddress">Address</label>
<input type="text" class="form-control" id="propaddress" placeholder="Enter the address">
</div>
<div class="form-group">
<label for="beds">Beds</label>
<input type="radio" name="beds" id="studio" value="0"> Studio
<input type="radio" name="beds" id="one" value="1"> One
<input type="radio" name="beds" id="two" value="2"> Two
<input type="radio" name="beds" id="three" value="3"> Three +
</div>
<div class="form-group">
<label for="baths">Baths</label>
<input type="radio" name="baths" id="one" value="1"> One
<input type="radio" name="baths" id="two" value="2"> Two
<input type="radio" name="baths" id="three" value="3"> Three +
</div>
<div class="form-group">
<label for="rental_price">Rent (in USD)</label>
<input type="text" class="form-control" id="rental_price" placeholder="$" pattern="[0-9]+([\.,][0-9]+)?">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea type="text" class="form-control vresize" id="description" placeholder="Describe your property" maxlength="255"></textarea>
</div>
<div class="form-group">
<label for="available"></label>
<input type="checkbox" name="available" value="available" id="available"> Property is available for showing
</div>
<div class="form-group">
<label for="contact_email">Contact Email</label>
<input type="text" class="form-control" id="contact_email" placeholder="Enter your contact email">
</div>
</form>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-success" data-dismiss="modal" onclick="App.sellArticle(); return false;">Submit</button>
<button type="button" class="btn" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="footer" class="container">
<nav class="navbar navbar-default navbar-fixed-bottom">
<div class="navbar-inner navbar-content-center text-center">
<p class="text-muted" credit><a href="http://www.axbean.com">AXbean</a> - © 2018</a></p>
</div>
</nav>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/RentalApp.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/web3.min.js"></script>
<script src="js/truffle-contract.js"></script>
</body>
</html>
RENTALAPP.JS:
App = {
web3Provider: null,
contracts: {},
account: 0x0,
loading: false,
init: function() {
return App.initWeb3();
},
initWeb3: function() {
// initialize web3
if(typeof web3 !== 'undefined') {
//reuse the provider of the Web3 object injected by Metamask
App.web3Provider = web3.currentProvider;
} else {
//create a new provider and plug it directly into our local node
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
web3 = new Web3(App.web3Provider);
App.displayAccountInfo();
return App.initContract();
},
displayAccountInfo: function() {
web3.eth.getCoinbase(function(err, account) {
if(err === null) {
App.account = account;
$('#account').text(account);
web3.eth.getBalance(account, function(err, balance) {
if(err === null) {
$('#accountBalance').text(web3.fromWei(balance, "ether") + " ETH");
}
})
}
});
},
initContract: function() {
$.getJSON('RentalContract.json', function(chainListArtifact) {
//added May24 to json file name
// get the contract artifact file and use it to instantiate a truffle contract abstraction
App.contracts.RentalContract = TruffleContract(chainListArtifact);
// set the provider for our contracts
App.contracts.RentalContract.setProvider(App.web3Provider);
// listen to events
App.listenToEvents();
// retrieve the article from the contract
return App.reloadArticles();
});
},
reloadArticles: function() {
//avoid reentry bugs
if(App.loading){
return;
}
App.loading = true;
// refresh account information because the balance might have changed
App.displayAccountInfo();
var chainListInstance;
App.contracts.RentalContract.deployed().then(function(instance) {
chainListInstance = instance;
return chainListInstance.getArticlesForSale();
}).then(function(articlesIds) {
// retrieve the article placeholder and clear it
$('#articlesRow').empty();
for(var i = 0; i < articlesIds.length; i++){
var articleId = articlesIds[i];
chainListInstance.articles(articleId.toNumber()).then(function(article){
App.displayArticle(article[0], article[1], article[3], article[4], article[5]);
});
}
App.loading = false;
}).catch(function(err) {
console.error(err.message);
App.loading = false;
});
},
displayArticle: function(id, seller, beds, baths, propaddress, rental_price, property_type, description, available, contact_email) {
var articlesRow = $('#articlesRow');
//var etherPrice = web3.fromWei(price, "ether");
var articleTemplate = $("#articleTemplate");
//articleTemplate.find('.panel-title').text(propaddress);
articleTemplate.find('.beds').text(beds);
articleTemplate.find('.baths').text(baths);
articleTemplate.find('.propaddress').text(propaddress);
articleTemplate.find('.rental_price').text(rental_price);
articleTemplate.find('.property_type').text(property_type);
articleTemplate.find('.description').text(description);
articleTemplate.find('.available').text(available);
articleTemplate.find('.contact_email').text(contact_email);
// articleTemplate.find('.article_price').text(etherPrice + " ETH");
articleTemplate.find('.btn-buy').attr('data-id', id);
// articleTemplate.find('.btn-buy').attr('data-value', etherPrice);
//seller
if(seller == App.account){
articleTemplate.find('.article-seller').text("You");
articleTemplate.find('.btn-buy').hide();
}else{
articleTemplate.find('.article-seller').text(seller);
articleTemplate.find('.btn-buy').show();
}
//add this new article
articlesRow.append(articleTemplate.html());
},
sellArticle: function() {
// retrieve the detail of the article
// var _article_name = $('#article_name').val();
var _description = $('#description').val();
var _beds = $('#beds').val();
var _baths = $('#baths').val();
var _propaddress = $('#propaddress').val();
var _rental_price = $('#rental_price').val();
var _property_type = $('#property_type').val();
var _available = $('#available').val();
var _contact_email = $('#contact_email').val();
// var _article_price = $('#article_price').val();
// var _price = web3.toWei(parseFloat($('#article_price').val() || 0), "ether");
if((_description.trim() == '') || (rental_price == 0)) {
// nothing to sell
return false;
}
App.contracts.RentalContract.deployed().then(function(instance) {
return instance.sellArticle(_description, _beds, _baths, _propaddress, _rental_price, _property_type, _available, _contact_email, {
from: App.account,
gas: 500000
});
}).then(function(result) {
}).catch(function(err) {
console.error(err);
});
},
// listen to events triggered by the contract
listenToEvents: function() {
App.contracts.RentalContract.deployed().then(function(instance) {
instance.LogSellArticle({}, {}).watch(function(error, event) {
if (!error) {
$("#events").append('<li class="list-group-item">' + event.args._propaddress + ' is now for sale</li>');
} else {
console.error(error);
}
App.reloadArticles();
});
instance.LogBuyArticle({}, {}).watch(function(error, event) {
if (!error) {
$("#events").append('<li class="list-group-item">' + event.args._buyer + ' bought ' + event.args._propaddress + '</li>');
} else {
console.error(error);
}
App.reloadArticles();
});
});
},
buyArticle: function() {
event.preventDefault();
// retrieve the article price and data
var _articleId = $(event.target).data('id');
var _price = parseFloat($(event.target).data('value'));
App.contracts.RentalContract.deployed().then(function(instance){
return instance.buyArticle(_articleId, {
from: App.account,
value: web3.toWei(_price, "ether"),
gas: 500000
});
}).catch(function(error) {
console.error(error);
});
}
};
$(function() {
$(window).load(function() {
App.init();
});
});
合同:
pragma solidity ^0.4.18;
import "./Ownable.sol";
contract RentalContract is Ownable {
struct Article{
uint id;
address seller;
address buyer;
uint beds;
uint baths;
string propaddress;
uint256 rental_price;
uint property_type;
string description;
bool available;
string contact_email;
}
mapping(uint => Article) public articles;
uint articleCounter;
event LogSellArticle(
uint indexed _id,
address indexed _seller,
// uint _beds,
// uint _baths,
string _propaddress,
uint256 _rental_price
// uint _property_type,
// string _description,
// bool _available,
// string _contact_email
);
event LogBuyArticle(
uint indexed _id,
address indexed _seller,
address indexed _buyer,
// uint _beds,
// uint _baths,
string _propaddress,
uint256 _rental_price
// uint _property_type,
// string _description,
// bool _available,
// string _contact_email
);
function kill() public onlyOwner {
selfdestruct(owner);
}
function sellArticle(uint _beds, uint _baths, string _propaddress, uint256 _rental_price, uint _property_type, string _description, bool _available, string _contact_email) public {
articleCounter++;
articles[articleCounter] = Article(
articleCounter,
msg.sender,
0x0,
_beds,
_baths,
_propaddress,
_rental_price,
_property_type,
_description,
_available,
_contact_email
);
// LogSellArticle(articleCounter, msg.sender, _beds, _baths, _propaddress, _rental_price, _property_type, _description, _available, _contact_email);
LogSellArticle(articleCounter, msg.sender, _propaddress, _rental_price);
}
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.property_type, article.description, article.available, article.contact_email);
LogBuyArticle(_id, article.seller, article.buyer, article.propaddress, article.rental_price);
}
}
答案 0 :(得分:0)
看起来你正在将第10个参数传递给sellArticle函数,是:
{
from: App.account,
gas: 500000
}
但是在你的合同中,函数sellArticle不是一个应付函数,所以我认为它会抛出一个错误。你可以尝试付款。