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
andsolc
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 mysolc
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:Now, just use the fresh solc version you just compiled, which is
./build/solc/solc