Is there a way to access Ethereum Smart Contract's variables by name in JavaScript?

6

2

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

Posted 2015-06-18T02:40:30.947

Reputation: 41 594

Answers

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

Posted 2015-06-18T02:40:30.947

Reputation: 246

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 2015-06-18T19:59:43.707

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 2015-06-21T00:23:43.023

@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 2015-06-22T01:07:47.707

You seem to use an outdated solidity compiler. string32 has been replaced by bytes32 and also your interface json looks incomplete.chriseth 2015-06-22T10:06:36.710

@chriseth Hmm, interesting. I will have to give a "cutting edge" version a go then...ThePiachu 2015-06-23T19:28:05.797

@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 2017-11-09T05:55:04.290

@stone212 the term was renamed to "getter" in the meantime.chriseth 2017-11-13T17:29:03.850

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

Posted 2015-06-18T02:40:30.947

Reputation: 111

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

Posted 2015-06-18T02:40:30.947

Reputation: 2 417

yeah! thank you very much! save me a lot of time! save my day!尤川豪 2018-02-05T07:56:04.487