I have a contract running on the testnet, and every time I need to call a function, after opening Geth I have to type (or paste):

primary = eth.accounts[0];
personal.unlockAccount(primary, 'mypassword');
var source = "contract FooContract {...}";
var compiled = web3.eth.compile.solidity(source);
var contract = web3.eth.contract(compiled.FooContract.info.abiDefinition);
var fooContract = contract.at("0xf00");

Is there a way to make geth remember that after I close it?

  • 2
  • 1
    This is a life-changer. Can you believe I used to make all my scripts wait for geth to be available, then open it, run the script and close it ? Talk about efficiency... It may be unrelated, but do you have a solution to execute scripts with argument ? My current solution is as ugly as can be... Jan 6 '17 at 16:40
  • 3
    I guess I can call the multipleCommand script with argument, and drop some $1 and $2 in the commands, that should work. I'm going to update my former question about arguments with your solutions, it's just way better. Jan 6 '17 at 16:48

Following on from your comments above that you are looking for a script that takes optional parameters, here is an example script with command line parameters that you can customise:

# ------------------------------------------------------------------------------
# Check account balance
# Works on Linux and OS/X. May work on Windows with Cygwin.
# Usage:
#   1. Download this script to checkBalance
#   2. `chmod 700 checkBalance`
#   3. Run `geth console` in a window.
#   4. Then run this script `./checkBalance` in a separate window.
# Parameters:
#   account    Account to check the balance. Defaults to GOLEM multisig
#   block      Blocknumber. Defaults to "latest"
# Sample Usage:
#   ./checkBalance
#   '0x7da82c7ab4771ff031b66538d2fb9b0b047f6cf9' at 'latest' has 770001.899999999999999999 ETH
#   ./checkBalance 0x7da82c7ab4771ff031b66538d2fb9b0b047f6cf9 2691189
#   '0x7da82c7ab4771ff031b66538d2fb9b0b047f6cf9' at '2691189' has 820002.9 ETH
# History:
#   * Jan 07 2017 - Version 1.0
# Enjoy. (c) BokkyPooBah 2016. The MIT licence.
# ------------------------------------------------------------------------------

# Leave ATTACHPARAMETER as undefined normally
# ATTACHPARAMETER="rpc:http://localhost:8545"
# ATTACHPARAMETER="ipc:$HOME/Library/Ethereum/geth.ipc"

# Golem multisig


# Uncomment the following line and comment the next line using // while debugging this script
# geth attach $ATTACHPARAMETER << EOF
geth attach $ATTACHPARAMETER << EOF | grep "Data: " | sed "s/Data: //"

var balance=web3.fromWei(eth.getBalance("$ACCOUNT", "$BLOCK"), "ether");
console.log("Data: '$ACCOUNT' at '$BLOCK' has " + balance + " ETH");


Reference: How to write a bash script that takes optional input arguments?

  • 1
    Is it possible to assign some of the variables of the javascript part to bash variables ? I don't really know what I can and can't do between geth attach <<EOF and the second EOF. If for example I want to save my balance into a variable, send a transaction, and save my balance afterwards in another variable, is it there a way to do that ? Jan 9 '17 at 14:57
  • I'm currently working on security testing some decentralised trustless exchange contracts for listing at cryptoderivatives.market . You can see my last version of testing scripts at github.com/bokkypoobah/TokenTrader/tree/master/testing/… . I read variables from files and pass them via script to geth JavaScript (search for PASSWORD). I save addresses and ABIs (see factoryData). (Updated for current version)
    Jan 15 '17 at 23:00
  • Just a tiny question, (I don't think I should open a new question for that) what does sed "s/^.*=//" do ? I looked some doc for sed and regex, but I can't make a definite conclusion. Does it keep only the part after = ? (I mean I know that's what it does but I don't understand how) Jan 16 '17 at 14:04
  • Yes. sed "s/{from}/{to}/" substitutes the from string with the to string. In the from string, ^ matches the start of the line, . matches any character, * operates on the previous item and matches zero or more of the last item and = matches =. So the command substitutes anything from the start of the line to the = character with a blank string. If your line is TEST=123, the sed command will change it to 123.
    Jan 16 '17 at 14:14
  • 1
    Great explanation, thanks! I added ? after = so I can do contract={...a=b...} and still get the whole thing, not just the part after the last =. I don't know if there are better places to store contracts than in the settings file (my project revolves around one single contract, maybe it makes less sense with different projects) Jan 16 '17 at 14:51

You are doing it wrong way around.

What you want to do is to have geth running as a daemon and then your JavaScript connects to Geth over web3.js / JSON-RPC protocol. (It's the same web3 object exposed that is available on geth prompt). You can run JavaScript scripts using node command.

Below is one example. You can find examples in this tutorial blog post: Programming Ethereum smart contract transactions in JavaScript .

Create a package.json for your project to install web3:

 npm install --save web3

First start geth in testnet / mining mode with Ropsten testnet genesis file:

   geth --rpc --rpcapi "db,eth,net,web3,personal" --verbosity 3 --rpccorsdomain "*" --cache 384 --datadir /home/ubuntu/.ethereum/ropsten --networkid 3 --mine

Then run a JavaScript file that connects to your geth and performs the necessary calls (not the same example as in your question, but you should get the idea):

/* Call the contract using web3-
 * To run:
 *        nvm use 7.2.1
 *       ./node_modules/babel-cli/bin/babel-node.js --presets es2015 ./tests/callcontract.js

import fs from "fs";
import Web3  from 'web3';

let web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));

// Fetch ABI - see blog post how to generate contracts.json
let source = fs.readFileSync("contracts/contracts.json");
let contracts = JSON.parse(source)["contracts"];
let abi = JSON.parse(contracts.SampleContract.abi);

// Get a proxy on our Ropsten contract
let SampleContract = web3.eth.contract(abi);
let contract = SampleContract.at('0xe0b79b3d705cd09435475904bf54520929eae4e8');

// Perform a transaction using ETH from the geth coinbase account
web3.personal.unlockAccount(web3.eth.coinbase, "");

// Set the account from where we perform out contract transactions
web3.eth.defaultAccount = web3.eth.coinbase;

let tx = contract.setValue(3000, {gas: 200000});
console.log("Our tx is https://testnet.etherscan.io/tx/" + tx);
  • This isn't a node.js script, is it ? You would use require instead of import, and it seems let isn't supported. Jan 18 '17 at 10:08
  • Please read the first comment in the script. Jan 18 '17 at 10:50
  • I don't understand why you would need to do that. You can change the syntax a little and run it with node callcontract.js. What are the benefits of doing that ? I'm using var Web3 = require('web3'); web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) var instead of lets and it works like a charm. Don't take it the wrong way, but I don't want to use things I don't understand. (If I can do with babel-cli I will unless you tell me why I should use it) Jan 18 '17 at 10:57
  • I am applying modern JavaScript development technologies to be able to work more productively using the latest ECMAScript standards, syntatic sugar and best development practices. I am not concerned if this is out of scope for the reader. Jan 18 '17 at 11:02
  • That's a very good reason, I didn't know about ECMAScript. I might not start using it right now, but your example is pretty useful nonetheless. Jan 18 '17 at 11:09

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.