[Ethereum] How to call a contract function that alters blockchain state on geth console

contract-developmentdappsgo-ethereumprivate-blockchainsolc

It should be easy, but I'm having a hard time using a simple smart contract described in the Solidity language reference called SimpleStorage. It only as one attribute, a setter and a getter, and I'm trying to use it inside a private testnet.

What I'm doing

This is the contract:

pragma solidity >=0.4.0 <0.7.0;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

After compiling and launching within a geth console session, I'm trying to verify the current value with get():

> contract.get()   # This is how I call a view function
0                  # the returned value is 0.

After verifying this, set some different value with set():

> contract.set.sendTransaction(15, {from: eth.accounts[0]})
"0xe520abe45178d9034b1bd071db4e0db43fd92e33fd1ea4a4bfaccc4333551c07"

We see the transaction that was issued. After waiting for this transaction to be mined, I try to verify if the value changed:

> contract.get()   
0                  # the value is still 0!

As we can see, the value was not updated! What am I missing?

If I take the transaction hash, I can verify it was actually mined with web3.eth.getTransactionReceipt and web3.eth.getTransaction:

> web3.eth.getTransactionReceipt("0xe520abe45178d9034b1bd071db4e0db43fd92e33fd1ea4a4bfaccc4333551c07")
{
    blockHash: "0x17cb0d49e008032fcca7dce0e369985f6942a7bde96b76f3c37ee3a82f8bae6f",
    blockNumber: 254,
    contractAddress: null,
    cumulativeGasUsed: 90000,
    from: "0x221a8435a32a7212298038c0a4d12920a117153c",
    gasUsed: 90000,
    logs: [],
    logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    root: "0x4f64f7de49d4da235fa36e11ca04420d832a424121dc694c82183d4dc595d0aa",
    to: "0x9170addc770a6753d58614c184d4547a805c3217",
    transactionHash: "0xe520abe45178d9034b1bd071db4e0db43fd92e33fd1ea4a4bfaccc4333551c07",
    transactionIndex: 0
}

Above, notice the field gasUsed. Doesn't it indicate that the transaction was actually added to the chain? Also, why is contractAddress null? How could I fix that?

> web3.eth.getTransaction("0xe520abe45178d9034b1bd071db4e0db43fd92e33fd1ea4a4bfaccc4333551c07")
{
    blockHash: "0x17cb0d49e008032fcca7dce0e369985f6942a7bde96b76f3c37ee3a82f8bae6f",
    blockNumber: 254,
    from: "0x221a8435a32a7212298038c0a4d12920a117153c",
    gas: 90000,
    gasPrice: 1000000000,
    hash: "0xe520abe45178d9034b1bd071db4e0db43fd92e33fd1ea4a4bfaccc4333551c07",
    input: "0x60fe47b10000000000000000000000000000000000000000000000000000000000000063",
    nonce: 12,
    r: "0x1045aecfef65d3097794fe9831b4296dabafe9e1ff4eadff63e51fb3b9ea7331",
    s: "0x74e8212e8dc46e046a594541993098ea0f5cdf44c643b8384926bbce17bb2e5a",
    to: "0x9170addc770a6753d58614c184d4547a805c3217",
    transactionIndex: 0,
    v: "0x42",
    value: 0
}

Additional Info

Private network info:

> eth.gasPrice
1000000000
> admin.nodeInfo.protocols.eth.difficulty
36301632

Geth info:

> geth version
Geth
Version: 1.8.27-stable
Git Commit: 4bcc0a37ab70cb79b16893556cffdaad6974e7d8
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10.4
Operating System: linux
GOPATH=
GOROOT=/usr/lib/go-1.10

Solidity compiler (solc) info:

> solc --version
solc, the solidity compiler commandline interface
Version: 0.5.9+commit.c68bc34e.Linux.g++

How I compiled the contract:

solc -o . --bin --abi SimpleStorage.sol

How I launched the contract:

var abi = [{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
var bin = "0x6080604052600c60005534801561001557600080fd5b5060c6806100246000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806360fe47b11460375780636d4ce63c146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050607e565b005b60686088565b6040518082815260200191505060405180910390f35b8060008190555050565b6000805490509056fea265627a7a7230582093a1e9fcbdcbfb91a91cd118203aba4ad0ccbe2b5822cdf1f019dbd9da66ff4764736f6c63430005090032"
var config = {
                from: web3.eth.accounts[0],
                data: bin,
                gas: '4700000'
    };
var callback = function(e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
        console.log('Contrato minerado! endereço: ' + contract.address);
    }

};

var contract_factory = web3.eth.contract(abi);
var contract = contract_factory.new(config, callback);

How I set up my own private testnet: following, roughly but not exactly, the steps in this guide: Running a “quick” Ethereum private network for experimentation and testing by Timothy McCallum.

The difference is I did not need to rewrite part of the geth Go code and recompile it.

Best Answer

So, after a lot of guessing and trying, I experimented switching geth and solc versions. I did that because I remember doing these stuff last year, and didn't have to go through so much hassle.

In the end, only switching solc version was enough. I replaced my solc version and repeated everything I had previously done, exactly the same way, and it worked.

I have no idea why this happened, and I hope I don't have to keep using older versions...

How I did it:

Head to the solidity language github page. Under "releases", I picked some version which dated to around early 2018, which was 0.4.22. So, clone it, switch to tags/0.4.22, and follow the steps to build from source:

git clone https://github.com/ethereum/solidity
cd solidity
git checkout tags/v0.4.22
./scripts/install_deps.sh
mkdir build
cd build
cmake .. && make

Now, just use the fresh solc version you just compiled, which is ./build/solc/solc