3

A function in my contract when called on the truffle develop command line gives output in BigNumber format. Here is what I wrote on the command line:

instance = contract.at('deployed address')

instance.getAge()

I tried instance.getAge().toNumber() but that throws an error saying that toNumber isn't defined. I checked How to convert BigNumber to Number in Truffle framework? however that doesnt seem to work on command line.

Similary outputs from functions returning bytes32 are in hex.I checked web3 return bytes32 string but web3.utils.toAscii(x) {x is any variable} throws an error

"Cannot read property toAscii of undefined"

I read the stack related to that and that also didn't help.

Ismael
  • 30,570
  • 21
  • 53
  • 96
Rahul Kothari
  • 306
  • 2
  • 11

1 Answers1

3

Contract function calls in Truffle return promises so you have to add a callback to get the response. If getAge() is declared as either constant, pure or view in the Solidity contract you can do instance.getAge().then(age => age.toNumber()) if it doesn't have any of those modifiers then you need to do instance.getAge.call().then(age => age.toNumber())

willjgriff
  • 1,658
  • 8
  • 13
  • Thanks! I similarly had a function getname()that should return string but yields hex as output. So for that should I type:

    instance.getname().then(name => web3.toAscii(name))

    ?

    – Rahul Kothari Jan 18 '18 at 11:28
  • No worries! Also you shouldn't have to convert the string return value of a function from hex. Is getName() declared with either constant, view, or pure after the function name as suggested above? If it isn't then consider adding it. If you can't add it for some reason use instance.getname.call() instead. – willjgriff Jan 18 '18 at 12:57
  • Ya it is constant So I did instance.getname().then(name => web3.toAscii(name)) . It did work, however it gave these strings of \u0000 padded after the name. Anyway to remove that? – Rahul Kothari Jan 18 '18 at 15:46
  • Where do you get the instance from? And does the function in Solidity return a string, eg it looks similar to this function getName() constant returns (string)? – willjgriff Jan 18 '18 at 15:58
  • `pragma solidity ^0.4.17;

    contract MyFirst {

    bytes32 name;

    function set(bytes32 newName) public { name = newName; }

    function get() public constant returns (bytes32){ return name; } }`

    I use bytes32 not string, because solidity doesnt function well with strings. It throws weird errors.

    – Rahul Kothari Jan 18 '18 at 16:33
  • bytes32 is a statically sized variable, so you won't be able to put a string into it that is larger than 32 bytes. string is a dynamically sized variable so you can put as large a string as you want in it. Unfortunately there are currently restrictions on passing dynamically sized variables, such as strings, between contracts and maybe between storage and memory which are probably the source of the weird errors. However, some of these limitations should be fixed in the next few months so hopefully you'll get less weird errors when using strings. – willjgriff Jan 18 '18 at 17:07
  • Sorry it was all a bit confusing.

    So this function getname - it should return bytes32. However, it instead returns hex. So I did instance.getname().then(name => web3.toAscii(name)). Now that works fine, except for a bit irritation coming from the padded u0000. Do you know a way to perhaps convert this hex output back to bytes32 without these u0000?

    – Rahul Kothari Jan 18 '18 at 19:17
  • You can remove the trailing zeros with a regex before converting it to Ascii which could be done with hexValue.replace(/0+$/, "") so all of it together could look like this instance.getname().then(hexValue => hexValue.replace(/0+$/, "")).then(hexNoTrailingZeros => web3.toAscii(hexNoTrailingZeros)) – willjgriff Jan 18 '18 at 22:42