У меня есть веб-страница HTML, на которой я передаю пользовательские записи в смарт-контракт, предназначенный для «хранения» записей в транзакциях. У меня работает большая часть приложения, но у меня проблемы с вызовом транзакции. Я продолжаю получать "недопустимое количество аргументов" или несоответствие типов.
Вот код веб-формы:
<form class="form-group" role="form">
<div class="form-group">
<label for="id">ID:</label>
<input type="number" class="form-control" id="id" placeholder="123">
</div>
<br>
<div class="form-group">
<label for="name">Name (First and Last:</label>
<input type="text" class="form-control" id="name" placeholder="John Stamos">
</div>
<br>
<div class="form-group">
<label for="email">Email Address:</label>
<input type="email" class="form-control" id="email" placeholder="blockchain@gmail.com">
</div>
<br>
<div class="form-group">
<label for="comment">Comment:</label>
<textarea class="form-control" rows="5" id="comment" placeholder="I learned..."></textarea>
</div>
</form>
Вот код контракта солидности:
pragma solidity ^0.4.15;
contract simpleStorage {
struct BizCard {
uint id;
bytes32 name;
bytes32 email;
string comment;
}
//sets counter of cards
uint public count = 0;
//creates a map of key values where key is an unsigned int and value is an instance of a card
mapping (uint => BizCard) cards;
//creates card object; adds data to the mapping and increments the shadow key count
function createCard(uint id, bytes32 name, bytes32 email, string comment) {
cards[count] = BizCard(id, name, email, comment);
count++;
}
//constant method to get card information, does not cost gas or change contract state
function getCard(uint index) constant returns (uint id, bytes32 name, bytes32 email, string comment) {
id = cards[index].id;
name = cards[index].name;
email = cards[index].email;
comment = cards[index].comment;
}
function getCardById(uint id) constant returns (uint idRet, bytes32 name, bytes32 email, string comment, uint status) {
for (var i = 0; i < count; i++) {
if (cards[i].id == id) {
idRet = cards[i].id;
name = cards[i].name;
email = cards[i].email;
comment = cards[i].comment;
return;
}
}
}
}
Вот код Javascript через web3:
function createCard() {
web3.personal.unlockAccount(web3.eth.accounts[0], 'scrubbed');
var txn = contract_instance.createCard($("id").val(), $("name").val(), $("email").val(), $("comment").val(), { from: web3.eth.accounts[0], gas: 300000 }, function (error, result) {
if (error) {
console.log(error);
} else {
var txhash = result;
console.log(result);
console.log(txn);
}
});
}
Я на 99% уверен, что одна из проблем заключается в том, что входные данные из «имени» и «электронной почты» поступают в виде строки, но контракт ищет байты32. Не уверен, как синтаксически перекодировать это. Также возможно, что Jquery, который я использую для извлечения данных из формы, не работает, но я думаю, что он закодирован правильно.
Uncaught Error: Invalid number of arguments to Solidity function
at Object.InvalidNumberOfSolidityArgs (web3.min.js:1)
at c.validateArgs (web3.min.js:1)
at c.toPayload (web3.min.js:1)
at c.sendTransaction (web3.min.js:1)
at c.execute (web3.min.js:1)
at createCard ((index):52)
at HTMLButtonElement.onclick ((index):165)
InvalidNumberOfSolidityArgs @ web3.min.js:1
c.validateArgs @ web3.min.js:1
c.toPayload @ web3.min.js:1
c.sendTransaction @ web3.min.js:1
c.execute @ web3.min.js:1
createCard @ (index):52
onclick @ (index):165
Если вы используете bytes32, вы должны убедиться, что размер передаваемых значений ограничен 32 байтами. (Вы можете использовать некоторые внешние проверки, я не вижу проверки в опубликованном вами коде.)
Если не гарантируется или нецелесообразно ограничивать его, вы можете использовать строку произвольной длины.
Хорошее объяснение, почему и когда использовать bytes32 и string, можно найти здесь .
name = "name"
и email = "email@email.com"
и увеличить лимит газа$("id").val(), $("name").val(), $("email").val(), $("comment").val()
зарегистрировав их в консоли
Форрест
Исмаэль
createCard
не определено, и поэтому web3 считает, что у него меньше параметров, чем ожидалось.