0

I have a HTML web page where I am feeding user entries into a smart contract that is designed to "store" the entries in transactions. I have most of the application working, but I'm having trouble with the transaction call. I keep getting "invalid number of arguments error" or a type mismatch.

Here is the webform code:

<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="[email protected]">
    </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>

Here is the solidity contract code:

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;
            }
        }
    }
}

Here is the Javascript code via 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);
        }
    });
}

I am 99% sure that one of the issues is that inputs from "name" and "email" are going in as string, but the contract is looking for bytes32. Not sure how syntactically to recode that. It is also possible that the Jquery I'm using to pull the data from the form isn't working, but I think it's coded correctly

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
2
  • Here is the error info: 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
    – Forrest
    Commented Oct 11, 2017 at 14:22
  • I've edited your question to add the formatted the error, it may be wrong please review and edit. My hunch is that one of the values in the call to createCard is undefined, and so web3 think it has fewer parameters than expected.
    – Ismael
    Commented Oct 12, 2017 at 21:18

1 Answer 1

0

If you are using bytes32 you have to make sure the size of the values passed are limited to 32 bytes. (You may use some front-end validations, I see no validation in the code you posted.)

If it's not guaranteed or practical to limit it you may use string which is arbitrary length.

A good explanation on why and when to use bytes32 and string can be found here.

11
  • Thanks, I am adding validation at the end - I will do some research on the string/bytes usage
    – Forrest
    Commented Oct 10, 2017 at 20:30
  • you got the point where it goes wrong? Commented Oct 10, 2017 at 20:31
  • Do you get the same error when inputs are shorter than 32 bytes? Commented Oct 10, 2017 at 20:32
  • the error is thrown on the line that the functional call is on - createCard()... since I'm entering strings into the webform input I bet that's the issue
    – Forrest
    Commented Oct 10, 2017 at 20:35
  • I tried entering 0x1231232 into the forms and still no go - so type matching can't be the issue
    – Forrest
    Commented Oct 10, 2017 at 20:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.