Reading contract constants via API

I'm looking for a simple way to read the constant out of a contract via an API (such as https://etherscan.io/apis#proxy ).

Basically I want to read the current number of proposals out from theDAO contract, but without having to run a full node myself.

So I want to get able to call the numberOfProspals() from contract 0xbb9bc244d798123fde783fcc1c72d3bb8c189413

How can I do it?

Comments

  • astroastro Member Posts: 16
    There appears to be an "eth_call" method in the API you linked. Would this work for what you're trying to do?
  • dave123124dave123124 Member Posts: 11
    edited May 2016
    It should but I don't know how to use the eth_call API function, it doesn't seem to have much documentation, and accepts a "data" field in hex format?

    So I want to call the numberOfProspals() function in theDAO contract; what hex data should I put into the hex field for the eth_call ?
  • dave123124dave123124 Member Posts: 11
  • astroastro Member Posts: 16
    That's the documentation of the RPC call the API is exposing. In your initial post you just said you didn't want to run the full node yourself. Do you understand how ETH messaging works and how to make contract calls?
  • dave123124dave123124 Member Posts: 11
    edited May 2016
    I have figured out the answer of how to use a 3rd party API to get the numberOfProposals() from theDAO contract:

    https://api.etherscan.io/api?module=proxy&action=eth_call&to=0xbb9bc244d798123fde783fcc1c72d3bb8c189413&data=0x8d7af473&apikey=my-api-key

    Explanation:
    In order to do an eth_call via the etherscan API you must first get the hash identifier of the function that you want to call. In my case I want to call numberOfProposals(), which is calculated as:

    web3.sha("numberOfProposals()").substr(0,8)
    8d7af473
    , then stick a 0x on the front to indicate that it is a hex value.

    If the function takes parameters then there gets more complex and I have not yet successfully been able to do that.
  • astroastro Member Posts: 16
    The parameters are a bit tricky. Essentially the "encoded" value of the parameter gets appended to the method signature (the 4 bytes) as part of the data payload. Make sure you're taking the entire method signature though. So, for instance, if I have a method foo(uint32 x, uint32 y) I pass in "foo(uint32,uint32)" to be hashed. (results in 0x21ff5444)

    The two parameters to the method get "encoded", which means represented in hex and padded to 32 bytes for the unit32s. So if I want to put in 16 for x and 504 for y, I first convert them to hex (10 & 1F8) and then pad them to 32 bytes each (0x0000000000000000000000000000000000000000000000000000000000000010 & 0x00000000000000000000000000000000000000000000000000000000000001F8). The leading "0x" is only used once, so the method call would look like:
    0x21ff5444000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001F8

    Arrays and dynamic types get really crazy because of how they are converted. The ABI spells all of this out, but it's definitely not meant to be done by hand. https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI

    Also note that if the number of bytes are not specified for the int or uint, they are assumed to be the full 256 byte types.

    It's worth noting that return values are also encoded, so make sure that you are accounting for that when parsing the return values. For simple return types, they are just hex values, but if the method returns an array you'll have to convert it back out.
Sign In or Register to comment.