Создание транзакции из веб-формы - неверное количество аргументов

У меня есть веб-страница 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
Вот информация об ошибке: 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) в c.sendTransaction (web3.min.js:1) в c.execute (web3.min.js:1) в createCard ((index):52) в 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 @ (индекс): 52 onclick @ (индекс): 165
Я отредактировал ваш вопрос, чтобы добавить отформатированную ошибку, это может быть неправильно, пожалуйста, просмотрите и отредактируйте. Я подозреваю, что одно из значений в вызове createCardне определено, и поэтому web3 считает, что у него меньше параметров, чем ожидалось.

Ответы (1)

Если вы используете bytes32, вы должны убедиться, что размер передаваемых значений ограничен 32 байтами. (Вы можете использовать некоторые внешние проверки, я не вижу проверки в опубликованном вами коде.)

Если не гарантируется или нецелесообразно ограничивать его, вы можете использовать строку произвольной длины.

Хорошее объяснение, почему и когда использовать bytes32 и string, можно найти здесь .

Спасибо, я добавляю проверку в конце - я проведу небольшое исследование использования строк/байтов.
вы поняли, где это идет не так?
Вы получаете ту же ошибку, когда входные данные короче 32 байт?
ошибка возникает в строке, на которой находится функциональный вызов - createCard()... так как я ввожу строки в ввод веб-формы, я уверен, что это проблема
Я попытался ввести 0x1231232 в формы, и все еще не работает, так что соответствие типов не может быть проблемой.
попробуйте указать простые строки, такие как name = "name"и email = "email@email.com"и увеличить лимит газа
если все еще не работает, опубликуйте полный код прочности контракта здесь.
добавлен код полной прочности
извините за поздний ответ, вы только что проверили значения, $("id").val(), $("name").val(), $("email").val(), $("comment").val()зарегистрировав их в консоли
И проверьте правильность определения ABI для контракта
Вы решили эту проблему?