7

Say I have a simple smart contract:

contract Simple {
    string32 message;

    function Simple() {
        message = "Hello world!";
    }
}

How can I easily access the message variable by name in JavaScript? It looks like there is some way to map functions into JS, but variables appear to only be accessible through a complicated way:

var storageObject = web3.eth.storageAt(contractAddress);
document.getElementById('fullName').innerText = web3.toAscii(storageObject['0x']) + ' ' + web3.toAscii(storageObject['0x01']);
ThePiachu
  • 42,931
  • 25
  • 138
  • 347

3 Answers3

7

Note that this question has been automatically mapped to reddit and answered there.

If you declare your state variables as public, a function to read their values will be automatically created by the compiler ("accessor function"). If you use the rich interface provided by web3.js, you can create a javascript contract object and just call message() on that to get the respective value.

For arrays and mappings, the compiler will generate a function that has additional arguments which correspond to the indexes. For example, for a variable mapping(uint => uint[]) public data; the function will be equivalent to function data(uint x, uint y) constant returns (uint) { return data[x][y]; }.

chriseth
  • 256
  • 1
  • 2
  • Hmm, I tried using the `public` function. I added the function to the contract descriptor, but now that I call it, the javascript thinks I want to send a transaction to the contract to invoke that function... – ThePiachu Jun 18 '15 at 19:59
  • Which version of web3.js are you using? The most current one should decide between a local call and a transaction automatically, with older ones you had to be explicit. Can you post the JSON for the ABI for the contract? – Rob Myers Jun 21 '15 at 00:23
  • @RobMyers I'm trying to run it in AlethZero v0.8.2 . My current test code is available at https://github.com/ThePiachu/EtherTest . – ThePiachu Jun 22 '15 at 01:07
  • You seem to use an outdated solidity compiler. `string32` has been replaced by `bytes32` and also your interface json looks incomplete. – chriseth Jun 22 '15 at 10:06
  • @chriseth Hmm, interesting. I will have to give a "cutting edge" version a go then... – ThePiachu Jun 23 '15 at 19:28
  • @chriseth Can you explain what you mean about the "accessor function"? I went to that link, and it's been moved, and the phrase "accessor function" isn't anywhere on the new page. What I want is to access a string that I coded into a contract. Preferably I want to see it on the blockchain explorer. – stone.212 Nov 09 '17 at 05:55
  • @stone212 the term was renamed to "getter" in the meantime. – chriseth Nov 13 '17 at 17:29
  • Who pays the cost of reading that data and where does the request go? Is it something that ETH nodes have to provide for free? – Dominic Nov 23 '21 at 00:40
1

You should check out web3.eth.contract - it should have exactly what you need. https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethcontract

Tim Coulter
  • 111
  • 1
1

Here is a JavaScript code for Node.JS to read a

  • You need the contract Solidity source code to get ABI

  • With this ABI and web3 convenience methods you can read the contract data

Example:

var Web3 = require('web3');
var solc = require("solc");
var fs = require('fs');

// Connect to a geth server over JSON-RPC
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

console.log("Talking with a geth server", web3.version.api);

// Read standard token contract from https://www.ethereum.org/token
var sourceCode = fs.readFileSync('sol/token.sol','utf8')
var compiled = solc.compile(sourceCode);
var abiArray = compiled.contracts["MyToken"].interface;
abiArray = JSON.parse(abiArray);

// Create a proxy object to access the smart contract
var MyContract = web3.eth.contract(abiArray);

// instantiate by address
var address = "0x091cc7F4ACA751a6b8A4101715d6B07CD4232341";
var contractInstance = MyContract.at(address);

// All public variables have automatically generated getters
// http://bitcoin.stackexchange.com/a/38079/5464
var result = {
  "totalSupply": contractInstance.totalSupply(),
  "symbol": contractInstance.symbol(),
  "name": contractInstance.name(),
};
console.log(JSON.stringify(result));
Mikko Ohtamaa
  • 2,437
  • 16
  • 32