0

So I have a function where I am asking the user to send two strings and 1 ether at the same time. When I execute the function in the console, the solidity contract is updated. When I execute the same function in Javscript, Metamask opens, I pay some gas, but then Metamask hangs and the solidity contract is never updated.

UPDATE: I assume I am somehow making the call via Metamask incorrectly (I can't figure out how) because when I remove MetaMask and use my fall back web3 provider (Ganache) the call goes through without problem.

Relevant code:

Solidity function:

 function makeClaim(string _name, string _ipfs) payable public {
        //many things to check- how many claims they make, did they make a claim before, etc...
        countevents[_name] += 1;
        database[_name][countevents[_name]] = _ipfs;
        victimDatabase[msg.sender][_name].person = msg.sender;
        victimDatabase[msg.sender][_name].stake = msg.value;
        victimDatabase[msg.sender][_name].time = block.timestamp;
    }

Truffle Console: (this works- as in it updates the solidity contract)

Shitlist.deployed().then(function(instance) {console.log(instance.makeClaim('rabbit', 'cake', {value: web3.toWei('1', 'ether')}).then(function(v) {console.log()}))})

Result:

Promise {
  <pending>,
  domain: 
   Domain {
     domain: null,
     _events: 
      { removeListener: [Function: updateExceptionCapture],
        newListener: [Function: updateExceptionCapture],
        error: [Function: debugDomainError] },
     _eventsCount: 3,
     _maxListeners: undefined,
     members: [] } }
undefined

In Javascript:

$(function(){
  $('#btnfunctionmakeClaim').click(function() {
    window.claimMade = document.getElementById('claim_details').value;
    window.claimName = document.getElementById('name_accused').value;

    Shitlist.deployed().then(function(contractInstance) 
    {console.log(contractInstance.makeClaim('claimMade', 'claimName', {value: web3.toWei('1', 'ether'), gas: 500000, from: web3.eth.accounts[0]}).then(function(v) 
    {console.log()}))});

    })
  })

As a note I declared my variables with "window." infront of them as previously I was getting a "variable not defined" for "claimMade".

The Console in the browser gives me this:

Promise {<pending>}__proto__: Promise[[PromiseStatus]]: "pending"[[PromiseValue]]: undefined

For reference here is the entire code:

HTML:

<!DOCTYPE html>
<html>
<head>
 <title>Decentralized Voting App</title>
 <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
 <link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' type='text/css'>
 <style>
   </style>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shitlist2</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Abel">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Londrina+Shadow">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Londrina+Solid">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans">
<link rel="stylesheet" href="assets/css/styles.min.css" rel='stylesheet' type='text/html'>
<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' type='text/css'>
</head>
<body>
    <div class="highlight-clean">
        <div class="container">
            <div class="intro">
                <h2 class="text-center" style="font-family:'Londrina Shadow', cursive;font-size:135px;margin-bottom:-13px;">SHITLIST</h2>
                <p class="text-center" style="font-family:'Open Sans', sans-serif;">Anonymously check and report names of alleged abusers.&nbsp;<br><br></p>
            </div>
            <div class="buttons"><a class="btn btn-primary" role="button" href="#" id="checknamebutton" data-toggle="modal" data-target="#checkname" style="font-family:'Open Sans', sans-serif;background-color:#c2a747;font-size:15px;">Check Name</a>
                <div class="modal fade"
                    role="dialog" tabindex="-1" id="checkname">
                    <div class="modal-dialog" role="document">
                        <div class="modal-content">
                            <div class="modal-header">
                                <h4 class="modal-title" style="font-family:'Londrina Solid', cursive;font-size:45px;">Check Name:</h4><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div>
                            <div class="modal-body"><input type="text" id="searchNameAccused" name="name_check" placeholder="...type here..." autofocus="" style="font-family:'Open Sans', sans-serif;padding-bottom:1px;margin-bottom:21px;">
                                <p style="font-family:'Open Sans', sans-serif;">Enter the name of the person or organization you would like to check. Spelling counts as does capitalization. The search only shows results for exact matches.</p>
                                <p id="returnedClaimNumber">Claims:&nbsp;</p>
                            </div>
                            <div class="modal-footer"><button class="btn btn-light" type="button" data-dismiss="modal" style="font-family:'Open Sans', sans-serif;">Close</button>
                                <button class="btn btn-primary" type="button" id="btnCheckName" style="font-family:'Open Sans', sans-serif;font-size:18px;" >Check Name</button></div>
                        </div>
                    </div>
                </div><button class="btn btn-light" type="button" id="makeclaimbutton" data-toggle="modal" data-target="#makeclaim" style="font-family:'Open Sans', sans-serif;background-color:#ff77a8;font-size:15px;color:rgb(255,255,255);">MAke Claim</button>
                <button
                    class="btn btn-light" type="button" id="getrefundbutton" data-toggle="modal" data-target="#getrefund" style="font-family:'Open Sans', sans-serif;background-color:#7ad1b5;color:rgb(255,255,255);font-size:15px;">Get ReFUND</button>
                    <div class="modal fade" role="dialog" tabindex="-1" id="makeclaim">
                        <div class="modal-dialog" role="document">
                            <div class="modal-content">
                                <div class="modal-header">
                                    <h4 class="modal-title" style="font-family:'Londrina Solid', cursive;font-size:44px;">MAKE CLAIM:</h4><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div>
                                <div class="modal-body">
                                    <p style="font-family:'Open Sans', sans-serif;">The name of the person or organization against who you are making a claim:&nbsp;</p>

                                    <input type="text" id="name_accused" name="name_accused" placeholder="...Name...">

                                    <p style="font-family:'Open Sans', sans-serif;">Details of the claim you are making.&nbsp;</p>

                                    <input type="text" id="claim_details" name="claim_details" placeholder="...What happened..." style="width:379px;padding-bottom:1px;">
                                </div>
                                <div class="modal-footer"><button class="btn btn-light" type="button" data-dismiss="modal">Close</button>
                                    <button class="btn btn-primary" type="button" id="btnfunctionmakeClaim" style="font-family:'Open Sans', sans-serif;font-size:14px;">Make Claim</button></div>
                            </div>
                        </div>
                    </div>
            </div>
        </div>
        <div class="container" style="max-width:458px;width:313px;">
            <div class="table-responsive" style="width:288px;">
                <table class="table">
                    <thead>
                        <tr style="width:476px;">
                            <th class="justify-content-center align-items-center align-content-center" id="status" style="font-family:Abel, sans-serif;">Status</th>
                        </tr>
                    </thead>
                    <tbody></tbody>
                </table>
            </div>
        </div>
        <div></div>
    </div>
    <div>
        <div class="modal fade" role="dialog" tabindex="-1" id="getrefund">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h4 class="modal-title" style="font-family:'Londrina Solid', cursive;font-size:38px;">Get Refund</h4><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div>
                    <div class="modal-body" style="font-family:'Open Sans', sans-serif;">
                        <p>You can request your refund after 1 year.&nbsp;</p><input class="justify-content-center" type="text" name="refundAddress" required="" placeholder="Ethereum Address"></div>
                    <div class="modal-footer"><button class="btn btn-light" type="button" data-dismiss="modal">Close</button><button class="btn btn-primary" type="button" id="claimRefund">Get Refund</button></div>
                </div>
            </div>
        </div>
    </div>
    <div class="footer-basic">
        <footer>
            <div class="social"><a href="#"><i class="icon ion-social-instagram"></i></a><a href="#"><i class="icon ion-social-snapchat"></i></a><a href="#"><i class="icon ion-social-twitter"></i></a><a href="#"><i class="icon ion-social-facebook"></i></a></div>
            <ul class="list-inline">
                <li class="list-inline-item"><a href="#">Home</a></li>
                <li class="list-inline-item"><a href="#">Services</a></li>
                <li class="list-inline-item"><a href="#">About</a></li>
                <li class="list-inline-item"><a href="#">Terms</a></li>
                <li class="list-inline-item"><a href="#">Privacy Policy</a></li>
            </ul>
            <p class="copyright">Company Name © 2017</p>
        </footer>
    </div>

</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.bundle.min.js"></script>
<script src="app.js"></script>
</html>

Javascript: (Not all the functions are implemented yet, I'm stuck on this particular problem)

// Import the page's CSS. Webpack will know what to do with it.
import "../stylesheets/app.css";

// Import libraries we need.
import { default as Web3} from 'web3';
import { default as contract } from 'truffle-contract'

import shitlist_artifacts from '../../build/contracts/Shitlist.json'

let Shitlist = contract(shitlist_artifacts);

function getClaims()
{
    name = document.getElementById('searchNameAccused').value;
    var number = Shitlist.checkClaimExists.call(name);
    var i;
    for (i = 1; i <= number; i++){
        var accusedName = $("<div/>");
        accusedName.text('Claim: ' + Shitlist.getClaimDetails.call(name, i));
        $('#numberofClaims').append(accusedName);

        /*document.getElementById('numberofClaims').innerHTML = number;*/

    }

};

$(function(){
  $('#btnCheckName').click(function() {
    name = document.getElementById('searchNameAccused').value;
    Shitlist.deployed().then(function(contractInstance) {
      contractInstance.checkClaimExists.call(name).then(function(v){
        $('#returnedClaimNumber').append(" " + name + " has the following claims: ");
        for (var i=1; i <= v; i++){
          let claimNumber = i;
          contractInstance.getClaimDetails.call(name, claimNumber).then(function(p){
            $('#returnedClaimNumber').append(" " + p);

          })

        };


      })
    }
  )
})});

$(function(){
  $('#btnfunctionmakeClaim').click(function() {
    window.claimMade = document.getElementById('claim_details').value;
    window.claimName = document.getElementById('name_accused').value;

    Shitlist.deployed().then(function(contractInstance) 
    {console.log(contractInstance.makeClaim('claimMade', 'claimName', {value: web3.toWei('1', 'ether'), gas: 500000, from: web3.eth.accounts[0]}).then(function(v) 
    {console.log()}))});

    /*Shitlist.deployed().then(function(contractInstance) {
      contractInstance.makeClaim.send(claimName, claimMade, {value: web3.toWei(1, 'ether'), gas: 140000, from: web3.eth.accounts[0]});
    */
    })
  })


$( document ).ready(function() {
 if (typeof web3 !== 'undefined') {
  console.warn("Using web3 detected from external source like Metamask")
  // Use Mist/MetaMask's provider
  window.web3 = new Web3(web3.currentProvider);
 } else {
  console.warn("No web3 detected. Falling back to http://localhost:7545. You should remove this fallback when you deploy live, as it's inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask");
  // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
  window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));
 }

 Shitlist.setProvider(web3.currentProvider);


});

Solidity:

pragma solidity ^0.4.21;

contract Shitlist{

    //mapping of times a Name is found
    mapping(string => uint) countevents;

    //mapping of name to mapping of case number to string of IPFS
    mapping(string => mapping(uint => string)) database;

    struct Victim {
        address person;
        uint stake;
        uint time;
    }

    //mapping of victim to accused to amount staked and when
    mapping(address => mapping(string =>Victim)) victimDatabase;

    uint RefundTime;
    uint MinimumStake;

    function Shitlist(uint _refundtime, uint _minimumStake) public {
        RefundTime = _refundtime;
        MinimumStake = _minimumStake;

    }

    function makeClaim(string _name, string _ipfs) payable public {
        //many things to check- how many claims they make, did they make a claim before, etc...
        countevents[_name] += 1;
        database[_name][countevents[_name]] = _ipfs;
        victimDatabase[msg.sender][_name].person = msg.sender;
        victimDatabase[msg.sender][_name].stake = msg.value;
        victimDatabase[msg.sender][_name].time = block.timestamp;
    }

    function checkClaimExists(string _name) view public returns(uint){
        //later they should check only 12 hours
        if(countevents[_name] == 0)
            return(0);
        else
            return(countevents[_name]);
    }

    function getClaimDetails(string _name, uint _number) view public returns(string){
        require(_number >= 1);
        require( keccak256(database[_name][_number]) != keccak256(""));
        return(database[_name][_number]);
    }

    function refundStake(string _name)  public {
        require(victimDatabase[msg.sender][_name].stake > 0);
        require(victimDatabase[msg.sender][_name].time <= block.timestamp + RefundTime);
        msg.sender.transfer(victimDatabase[msg.sender][_name].stake);

    }

}
  • Why are you calling makeClaim within console.log? Console.log is used in debugging to print values to javascript console. Also you are not using javascript promises correctly. Perhaps your problem is promises are not chained correctly. – Ismael Apr 2 '18 at 19:48
  • Why are you calling makeClaim within console.log? - inexperience. :-) That is a good point. I have to go through my promises better. However I did have confirmation from some other dev's that I am not alone with this problem today so perhaps it's metamask. (but more likely still me). I'll update when I find a fix, for now I'm on a deadline and just forced to used a local web3 provider. – Dennison Apr 3 '18 at 1:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.