Solidity Remix – How to Convert String to Address in Web3.js

remixsolidity

So, I've this contract that I'm running in remix. I pass the input value as "padur" and I see in console that the return value is {"0": "address: 0x000000000000000000000000000000000003fdfb"}. This basically means that the 'string' input that I gave got converted into 'address' type by my contract.

Question is – when I interact with this contract using web3js, I'm passing the value as string but it doesn't get converted (instead got an error – web3.js:14789 Uncaught Error: new BigNumber() not a number: kelambakkam). How do I go about this?

How does remix browser converts it while web3js is not able to convert? It's just base20 address isn't?

Contract:

contract Test {
    //address mg;
    function getString(address _mg) returns (address) {
         return _mg;
    }
}

Edit:

When I run this html page, I get an error that "web3.js:14789 Uncaught Error: new BigNumber() not a number: Padur". What's the fix?

<!doctype>
<html>
<head>
    <link rel="stylesheet" href="js/main.css">

    <script type="text/javascript" src="js/bignumber.js"></script>
    <script type="text/javascript" src="js/web3.js"></script>
    <script type="text/javascript">
        providerURL = "HTTP://127.0.0.1:7545";
        var abi = [{"constant":false,"inputs":[{"name":"_mg","type":"address"}],"name":"getString","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"}];
        contractAddress = "0x6f2014378e4d34382cf93d906762ff2d12cdb769";
        var Web3 = require('web3');
        var web3 = new Web3();
        web3.setProvider(new web3.providers.HttpProvider(providerURL)); 

        function callMethod() 
        {
            var MyContract = web3.eth.contract(abi);
            var myContractInstance = MyContract.at(contractAddress);

            var accountToSubmitNOC = web3.eth.accounts[0];
            var unlockAccount = web3.personal.unlockAccount(accountToSubmitNOC,'',300);
            var msg = document.getElementById('idString').value; //IS THIS CORRECT?     
            var txHash = myContractInstance.getString(msg, function (err, res) {if (!err) { console.log(err, res); document.getElementById("idReturnValue").innerText = JSON.stringify(res); }});
        }
    </script>
</head>
<body>
    <table border = 0>
        <tr>
            <td>String</td>
            <td><input type="text" id="idString" value="Padur"></input></td>
        </tr>
        <tr>
            <td><button type="button" onClick="callMethod();" id="btnSetString">Write</button></td>
        </tr>
        <tr>
            <td>Return Value =  <div id="idReturnValue"></div></td>
        </tr>
    </table>
</body>
</html>

Edit #2 –

With Bytes32 instead of address

pragma solidity ^0.4.0;
contract Test {
    //address mg;
    function getString(bytes32 _mg) returns (bytes32) {
         return _mg;
    }
}

<!doctype>
<html>
<head>
    <link rel="stylesheet" href="js/main.css">

    <script type="text/javascript" src="js/bignumber.js"></script>
    <script type="text/javascript" src="js/web3.js"></script>
    <script type="text/javascript">
        providerURL = "HTTP://127.0.0.1:7545";
        var abi = [{"constant":false,"inputs":[{"name":"_mg","type":"bytes32"}],"name":"getString","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"}];
        contractAddress = "0xce503c6b2111f4e76d8a43689bbbea794887d014"; //deployed in local ganache
        var Web3 = require('web3');
        var web3 = new Web3();
        web3.setProvider(new web3.providers.HttpProvider(providerURL)); 

        function callMethod() 
        {
            var MyContract = web3.eth.contract(abi);
            var myContractInstance = MyContract.at(contractAddress);

            var accountToSubmitNOC = web3.eth.accounts[0];
            var unlockAccount = web3.personal.unlockAccount(accountToSubmitNOC,'',300);
            var msg = document.getElementById('idString').value;
            var txHash = myContractInstance.getString(msg, function (err, res) {if (!err) { console.log(err, res); document.getElementById("idReturnValue").innerText = JSON.stringify(res); }});
        }
    </script>
</head>
<body>
    <table border = 0>
        <tr>
            <td>String</td>
            <td><input type="text" id="idString" value="Padur"></input></td>
        </tr>
        <tr>
            <td><button type="button" onClick="callMethod();" id="btnSetString">Write</button></td>
        </tr>
        <tr>
            <td>Return Value =  <div id="idReturnValue"></div></td>
        </tr>
    </table>
</body>
</html>

Best Answer

The fact that Remix doesn't raise an error for this invalid input is just a bug in the bn.js library. It was fixed in the master branch of bn.js to throw an exception, but there hasn't been a release since that fix.

If you really want to replicate this nonsense, install bn.js@4.11.8 (the current version) and do new BN('padur'). But you're just getting garbage from trying to parse the ASCII as a base-10 number despite the characters being outside the range 0-9, and future versions of the library will fix this bug by throwing an exception instead.