李婷婷 Lee Ting Ting · Follow
Published in · 6 min read · Jun 30, 2017
--
Since many tutorials, including the official tutorial on ethereum.org, have some errs(ex. the updated version of geth removed the solidity compiling function) which make it harder for beginners like me to get started, I decided to write this tutorial in the hope of expanding the Ethereum community.
I’m using mac. If you encounter any problem, please kindly let me know in the comments so I can update it accordingly:)
Open source tools & language used:
- Solidity: smart contract programming language
- geth (version 1.5.9): CLI for running ethereum node
- brew: package manager for MacOS.
Install it by typing this command in terminal:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
As starting from geth version 1.6.0, compiling solidity is no longer available, we cannot install it directly using brew(only the newest version package is provided there). Here we use geth version 1.5.9 and build it from source code.
- Download Source code (tar.gz)
In terminal:
cd “path of the file you just downloaded”
// in Mac, you can simply drag the folder to console to get the pathmake geth
This will generate an executable file in the “your current directory”/build/bin folder which can be moved to wherever you want to run it from. The binary is stand alone and doesn’t require any additional files.(Reference: https://github.com/ethereum/go-ethereum/wiki/Installing-Geth#build-it-from-source-code )
2. Then, create alias:
echo "alias geth159='your_folder_path/build/bin/geth'" >> ~/.bashrc
In my case, it is /Users/tina/Desktop/go-ethereum-1.5.9/build/bin/geth
To make the changes affected immediately:
source ~/.bashrc
To make what you editted in ~/.bashrc available upon every login
echo "source ~/.bashrc" >> ~/.profile
Now you can type geth159 whenever you want to launch geth :)
3. Install Solidity compiler
brew install solidity
4. launch your private net
First create a folder to store your blockchain data
mkdir privchain
Use geth to launch it
geth159 --rpc --rpcaddr 127.0.0.1 --rpcport 8545 --dev --datadir privchain
(Reference: https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options, https://stackoverflow.com/questions/33826018/in-ethereum-what-is-a-private-testnet-why-would-i-want-it-and-how-do-i-set-it )
Should see something like
INFO…. IPC endpoint opened: /Users/tina/privchain/geth.ipc
INFO….HTTP endpoint opened: http://127.0.0.1:8545
And if you open a new console and cd privchain
then ls
, you can see the originally empty dir is now having geth, geth.ipc, and keystore
5. Keep that Ethereum node running and open a new terminal. Use “geth attach” to connect to the node and open geth console
geth159 attach ipc://Users/tina/privchain/geth.ipc
// use your own ipc url here!
6. Now use the api commands as specified here https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console#personallistaccounts
(In geth console)
personal.listAccounts
output: []
personal.newAccount('')
// you can enter your password like newAccount(‘password_ya’)
output: [0x…….] // your newly created account address.
- Note that every time a new account is created, you should see .”..New wallet appeared..” In the console where you opened your private net
personal.listAccounts
// just to make sure you hv made the account successfully
output: [0x………]
7. Use the ethereum js api as specified here https://ethereumbuilders.gitbooks.io/guide/content/en/ethereum_javascript_api.html
(in geth console)
web3.eth.coinbase
// This property is read only and returns the coinbase address where the mining rewards go to.
output: [0x………] // the output should be the same as your newly created account address, cause it takes the first account you created as default value
8. Create your smart contract!
source = "contract test { function multiply(uint a) returns(uint d){return a * 7;}}"
9. Make sure your solidity compiler is installed
web3.eth.getCompilers() // the output should be ["Solidity"]
10. Compile your code
code = web3.eth.compile.solidity(source)
The output(the “code” you just created) is like a json object. The highlighted part is your bytecode, which you will need to create a smart contract, and the abi array, respectively.
{<stdin>:test: { code: "0x60606040523415600b57fe5b5b60918061001a6000396000f300606060405263ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663c6888fa181146039575bfe5b3415604057fe5b6049600435605b565b60408051918252519081900360200190f35b600781025b9190505600a165627a7a723058206a8cbef13138690601a279c73e208f9dcf42e4678d860038475fe555599593d60029", info: { abiDefinition: [{...}],
compilerOptions: "--combined-json bin,abi,userdoc,devdoc -- add-std --optimize", compilerVersion: "0.4.11", developerDoc: { methods: {} }, language: "Solidity", languageVersion: "0.4.11", source: "contract test { function multiply(uint a) returns(uint d){return a * 7;}}", userDoc: { methods: {} } }}}
*What is abi? You can see this as an api for machines as explained here.
When you write source code, you access the library though an API. Once the code is compiled, your application accesses the binary data in the library through the ABI.
11. Create a contract object by its abi
MyContract = web3.eth.contract(code["<stdin>:test"].info.abiDefinition)
(Official document on how to create a contract: https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethcontract )
12. Check if you have a default coinbase account (to which your mining reward goes) with ether
First set your coinbase address as account1
account1 = web3.eth.coinbase
Then Check its balance
web3.eth.getBalance(account1)
If the output is larger than 0, go on to the next step:
Otherwise, start mining to get some ether in it!
miner.start()
You should see the mining in progress in the other terminal where you opened your private net
Stop when you feel like having sufficient funds ;p
miner.stop()
Check your balance again
web3.eth.getBalance(account1)
13. Unlock account to enable it to send transactions (In this case, we have to pay the gas price for contract deploy). Here we use account1.
personal.unlockAccount(account1, '')
// you can replace '' with the password you set previously
14. Next, init the contract using the compiled code. In this case, it is code[“<stdin>:test”].code
You can also use other ways (ex. brower-solidity) to compile the contract and get this code. Here, replace the contract code with our “source” contract code, and click “contract details” at the bottom-right corner and you would be able to see the same bytecode.
*Note: browser solidity cannot work on safari. You can use chrome instead.
*Note: you can also set the contract to a previous one using the address of the contract you created before (contractInstance = MyContract.at(“address”);)
bytecode = code["<stdin>:test"].code
Estimate how many gas you will need to deploy this contract
web3.eth.estimateGas({data: bytecode})
15. Deploy contract and set callback function for our better understanding :)
contractInstance = MyContract.new({data: bytecode gas: 1000000, from: account1}, function(e, contract){if(!e){if(!contract.address){console.log("Contract transaction send: Transaction Hash: "+contract.transactionHash+" waiting to be mined...");}else{console.log("Contract mined! Address: "+contract.address);console.log(contract);}}else{console.log(e)}})
- Note: The value of param “gas” can be anything higher than the estimated gas costs
- Note: you may have to unlock your account1 again here.
Now you should see
In this console:
Contract transaction send: Transaction Hash: “your_transaction_hash” waiting to be mined…
In the other console for starting the private net:
… created “your_transaction_hash”
16. Your contract is now waiting be mined. You should see ‘Contract mined!` soon after the mining starts. After that, you can stop mining.
miner.start()
After you see
Contract mined! Address: 0xf1bc128edf9d7d4a7d567b50c1d8080cf58ef068
Ctrl+c
to go back to geth console and type
miner.stop()
- Note: Ctrl+C is to interrupt any process return to the simple console mode. Ctrl+D is to exit the console
17. Last, check if your contract is created successfully
eth.getCode(contractInstance.address) // the output should be the same as your bytecode
18. Call our contract function
contractInstance.multiply.call(6) // replace 6 with any unsigned int
Output: 42
- Note: call() is a local invocation of a contract function that does not broadcast or publish anything on the blockchain. The command “contractInstance.multiply(6)” will not work.
(Reference: https://ethereum.stackexchange.com/questions/765/what-is-the-difference-between-a-transaction-and-a-call)
- Another great guide on the greeter tutorial:
https://samsclass.info/141/proj/pEth1.htm
Covers how to make a contract available to other machines on the same private network and how to delete a contract
2. Blockchain visualization and charts:
Now you know how to set up a private network, mine ethers, compile and run smart contracts in Solidity.
This is actually my first article and first tutorial. Share it if you like it. I’m open to any suggestions! Thank you:)