TransWikia.com

Call deployed smart contract from web3.js

Ethereum Asked by Chun-Wei Chiang on October 23, 2020

I have small test smart contract, which is deployed to my test network. And I want to use a server to call the function in the contract. Here is the code:
payontime.sol

pragma solidity ^0.4.0;

contract payontime{
  address public remitter;
  address private remittee;
  uint value;
  bool public start;

  /*Only owner can use these function*/
  modifier onlyOwner(){
    if(msg.sender != remitter) throw;
    _;
  }

  /*Initialize the owner*/
  function payontime(address receiver) payable{
    remitter = msg.sender;
    value = msg.value;
    remittee = receiver;
    start = true;
    if(!remittee.send(value)){
        throw;
    }
  }

  function wakeUp() public returns (string){
    return "success" ; 
  }

  function getContractAddr() public returns(address){
    return this;
  }

  /*Get the remittee*/
  function getRemitee() public returns(address){
    return remittee;
  }
}

I use truffle serve and a webpage to new the contract.

app.js

import { default as Web3} from 'web3';
import { default as contract } from 'truffle-contract'
import payontime_artifacts from '../../build/contracts/payontime.json'
var payontime = contract(payontime_artifacts);

window.App = {
    sendCoin : function(){

        var sender = web3.eth.accounts[0];
        var receiver = document.getElementById('receiver').value;
        var amount =         parseInt(document.getElementById('amount').value);
    web3.eth.getBalance(receiver,function(error,result){
        if(!error){
            consol.log("Before transfer: " + result );
        }else{
            console.log("Error: " + error);
        }
    });

    var newContract = payontime.new(receiver,{from:sender, value:amount}).then(
        function(myPay){
            console.log(myPay.getContractAddr.call());
        }).then(
        function(){
            web3.eth.getBalance(receiver,function(error,result){
                if(!error){
                    console.log("After transfer: " + result );
                }else{
                    console.log("Error: " + error);
                }
            });
        });
    }
}

window.addEventListener('load', function() {
  // Checking if Web3 has been injected by the browser (Mist/MetaMask)
  if (typeof web3 !== 'undefined') {
    console.warn("Using web3 detected from external source. If you find that your accounts don't appear or you have 0 MetaCoin, ensure you've configured that source properly. If using MetaMask, see the following link. Feel free to delete this warning. :) http://truffleframework.com/tutorials/truffle-and-metamask")
    // Use Mist/MetaMask's provider
    window.web3 = new Web3(web3.currentProvider);
  } else {
    console.warn("No web3 detected. Falling back to http://localhost:8545. 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:8545"));
  }
  payontime.setProvider(web3.currentProvider);
});

app.js logs the address 0x1d379f2ab48ad20319e9f81cb45af415aa6f2966 , and I want to use this address to call the wakeUp() in the payontime.sol through another application index.js.

const Web3 = require('web3');

/* Connect to ethereum node */
const etherUrl = "http://localhost:8545";
const abi = [{"constant":false,"inputs":[],"name":"wakeUp","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"getContractAddr","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"remitter","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"start","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"getRemitee","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"inputs":[{"name":"receiver","type":"address"}],"payable":true,"type":"constructor"}];

let web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider(etherUrl));


/*Call the function which already deployed on ethereum network
  Notice: ABI have to modifeid when the smart contract code change*/
var contractInstance = web3.eth.contract(abi).at('0x1d379f2ab48ad20319e9f81cb45af415aa6f2966');
var reply = "false";
reply = contractInstance.wakeUp.call(function(error,result){
    if(error){
        console.log("Error");
        throw error;
    }else{
        return result;
    }
});
console.log(reply);

But there is an error message:
BigNumber Error: new BigNumber() not a base 16 number
I found it might be caused by not fully synced. I think it have some problem when I call the function in a deployed contract. So how can I call a deployed contract from web.js?

2 Answers

From documentation of web3.js 1.0 we can call method from web3js as :

myContract.methods.myMethod([param1[, param2[, ...]]])

Lets see the example

var Web3 = require('web3')
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
const abi = abi_of_contract
const Contract = web3.eth.contract(abi)
var contractaddress = address_of_deployed_contract
const contractInstance = Contract.at(contractaddress)

//here I am using default account as first account from the list of addresses in the rpc enabled node
web3.eth.defaultAccount = web3.eth.accounts[0]

//calling contract function wakeUp()  

 contractInstance.wakeUp(   
        {
            from:   web3.eth.defaultAccount,
            to:     contractaddress           
    });

Error Error: new BigNumber() not a base 16 number that you got may be due to address you have passed. Please make account that you are using as default account first. It may solve your problem.

Answered by Gopal ojha on October 23, 2020

The BigNumber() is not a base 16 number error can happen in many cases, yet the causes are not necessarily the same. I believe the original post's issue is with using Events that index on "string" types, which I'm running into as well. If my contract event marks a "string" type as "indexed", i get the same error. But if I restrict the "indexed" keyword to only "address" type, I'm fine. I'm trying to find documentation on what data types can be "indexed" in a contract event, but to no avail. My gut feeling is anything that can be parsed as a number (address, integers etc) might be OK. I don't think blockchain synching is the issue here. So try removing any indexes on string fields in the event definition for now until they fix the bug.

ref:- What does the Web3 "BigNumber not a base 16 number Error" mean

Answered by SwapnilKumbhar on October 23, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP