I wish to store strings on-chain.

From what I understand so far, I need to set up a contract, then I can send transactions (with a string) to that contract which will be stored. Is this the best way to do this?

So far I have been able to setup a contract, though if my previous method is suitable, how would I:

  1. Setup my contract to receive & send a string
  2. Setup my transaction to send & receive a string

Contract so far:

contract mortal {
    /* Define variable owner of the type address */
    address owner;
    string str;

    /* This function is executed at initialization and sets the owner of the contract */
    function mortal() { owner = msg.sender; }

    /* Function to recover the funds on the contract */
    function kill() { if (msg.sender == owner) selfdestruct(owner); }

    function set(string val) public {
        str = val;

    function get() public constant returns (string) {
        return str;

Not sure how to proceed with a send/receive transaction? Would I need to invocate both web3.eth.sendTransaction to send & web3.eth.call to receive? If so how could I do this?

  • First compile your Solidity code, get the bytecode and ABI. See this tutorial. Then you can deploy it in web3 and interact with your contract. Nov 15 '17 at 1:36
  • If you feel your question has been answered, could you please mark it so other users know. :)
    – Malone
    Nov 15 '17 at 12:46
  • 1
    Of course @Malone thanks, unfortunately I only get to work on this stuff at night time so wasn't able to give it a go until now.
    – joe
    Nov 15 '17 at 21:29

Please make sure that you've unlocked your eth.account[0] by executing personal.unlockAccount(eth.account[0]) before progressing. (Or whatever account you're sending from).

This code will deploy the contract to the network:

var mortalContract = web3.eth.contract([{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"val","type":"string"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]);
var mortal = mortalContract.new(
     from: web3.eth.accounts[0], 
     data: '0x6060604052341561000f57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506103948061005e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b51461005c5780634ed3885e146100715780636d4ce63c146100ce575b600080fd5b341561006757600080fd5b61006f61015c565b005b341561007c57600080fd5b6100cc600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506101ed565b005b34156100d957600080fd5b6100e1610207565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610121578082015181840152602081019050610106565b50505050905090810190601f16801561014e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101eb576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b565b80600190805190602001906102039291906102af565b5050565b61020f61032f565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102a55780601f1061027a576101008083540402835291602001916102a5565b820191906000526020600020905b81548152906001019060200180831161028857829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102f057805160ff191683800117855561031e565b8280016001018555821561031e579182015b8281111561031d578251825591602001919060010190610302565b5b50905061032b9190610343565b5090565b602060405190810160405280600081525090565b61036591905b80821115610361576000816000905550600101610349565b5090565b905600a165627a7a72305820a73bbe00b6880e0b6a1a9642179e82cc6ad84cac8cd8d5e76180484b2462d68c0029', 
     gas: 3000000
   }, function(e, contract){
    console.log(e, contract);
    if (typeof contract.address != 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);

This code will aid further interactions with the contract:

var MortalContract = web3.eth.contract(mortalContract.abi);        
var mortalContractInstance = MortalContract.at(mortal.address);        
mortalContractInstance.set("thisIsAnInterestingString", {from: eth.accounts[0], gas: 3000000});

The above code will deploy your mortal contract, set the string and then retrieve the string. The last call to mortalContractInstance.get(); will return the string that was set i.e. "thisIsAnInterestingString".

UPDATE: As a side note, I retrieved the abi and compiled bytecode of your mortal contract from here. I could've done this manually but this online tool made it easier.

Helpful Screen Shots

enter image description here enter image description here

Hope this helps.

  • Perfect thank you! Is there any benefit to using a tool like browser-solidity over getting it dynamically with bytecode: compiled.contracts[':mortal'].bytecode and ABI: JSON.parse(compiled.contracts[':mortal'].interface);? Also, is there a reason why I should unlock the account? What is the variable/object person? it is undefined for me...
    – joe
    Nov 15 '17 at 21:33
  • 1
    Probably not, they're more than likely using the same function under the hood. I do like to use the browser-solidity for an IDE. The reason you need to unlock your account is so that Geth (or whatever ethereum implementation you're using) can sign the transactions on your behalf. personal object is part of the web3 obj. You should have this if Web3 has been injected. (directly access via web3.personal)
    – Malone
    Nov 15 '17 at 22:15
  • Thanks again for providing help on this, I don't suppose you could suggest how I could get the data "thisIsAnInterestingString" after it has been .set() & I did not have the contract instance? In this case I want to get the data on a different page. I presumed I would be able to access this again with the transactionHash, is this possible?
    – joe
    Dec 18 '17 at 23:32
  • 1
    Nevermind just found that web3.eth.getTransaction is a thing!
    – joe
    Dec 19 '17 at 16:06

Your contract works fine:

it works


calling contract functions is easy in web3. first make sure you have the contract object

someContract = web3.eth.contract(contract.abi).at(contractAddress)

then all you have to do is


What's going on underneath is that web3 will call the rpc provider with send_transaction and it's up to the provider to sign the transaction with whatever wallet you have. In a browser, metamask will be the provider, it will intercept the send_transaction call and pop up the dialog box. Reads don't need signing, and work directly:


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.