You are on page 1of 32

Geth

ing started

Welcome to the Frontier!

TheFrontieristhefirstlivereleaseoftheEthereumnetwork.Assuchyouareenteringuncharted
territoryandyouareinvitedtotestthegroundsandexplore.Thereisalotofdanger,theremaystill
beundiscoveredtraps,theremayberavagingbandsofpirateswaitingtoattackyou,buttherealso
isvastroomforopportunities.

InordertonavigatetheFrontier,youllneedtousethecommandline.Ifyouarenotcomfortable
usingit,westronglyadviseyoutostepback,watchfromadistanceforawhileandwaituntilmore
userfriendlytoolsaremadeavailable.Remember,therearenosafetynetsandforeverythingyou
dohere,youaremostlyonyourown.

Hitching up your wagon.

TheFrontiertooliscalledGeth(theoldenglishthirdpersonsingularconjugationoftogo.Quite
appropriategivengethiswrittenin
Go
).Inordertogetit,openyourcommandlinetool(ifyouare
unsurehowtodothis,considerwaitingforamoreuserfriendlyrelease)andpastethecommand
below.

rubye"$(curlfsSL
https://raw.githubusercontent.com/cubedro/frontier.ethereum.org/master/bi
n/install.rb)"
Or,alternatively

rubye"$(curlfsSL
https://raw.githubusercontent.com/cubedro/frontier.ethereum.org/master/bi
n/install.rb)"

Pastetheaboveonelinerinyourterminalforanautomatedinstallscript.Thisscriptwilldetectyour
OSandwillattempttoinstalltheethereumCLI.Pleaseclickthebuttonbelowifyou'dliketoseea
stepbystepdescriptionoftheinstallerscript.

GethisamultipurposecommandlinetoolthatrunsafullEthereumnodeimplementedinGo.It
offersthreeinterfaces:thecommandlinesubcommandsandoptions[link],aJSONRPCserver
andaninteractiveconsole.Forthepurposesofthisguide,wewillfocusontheConsole,a
javascriptenvironmentthatcontainsallthemainfeaturesyouprobablywant.Typethecodebelow
onyourterminal

gethconsole2>>geth.log

Youarereadytostart.The2>>geth.logcreatesatextfilewiththeoutputofyourconsole.Ona
linuxmachineorMacOSyoucanrunoneterminalwiththegethconsoleandasecondonewith
theloggingoutputbyopeninganewterminalandtyping:tty
Theoutputwillbesomethinglike:
/dev/pts/13
(oronMac
/dev/tty002
).Theninyourmain
terminaltype:

gethconsole2>>/dev/pts/13
Thiswillallowyoutomonitoryournode
withoutclutteringyourconsole
.

Thegethconsolehashistorythatpersistsbetweensessions.Youcannavigateyourcommand
historybyusingtheupanddownarrowkeys.

Tip:
sometimesyoumightnotneedtoconnecttothelivepublicnetwork,youcaninsteadchoose
tocreateyourownprivatetestnet.Thisisveryusefulifyoudon'tneedtotestexternalcontracts
andwantjusttotestthetechnology,becauseyouwon'thavetocompetewithotherminersandwill
easilygeneratealotoftestethertoplayaround(replace12345withanynumber

gethnetworkid12345console

Ifyouuseaprivatetestnet,itmaybeagoodideatostartwitha'fresh'blockchain,andnotthereal
blockchain.Otherwise,inordertosuccessfullymineablock,you'llneedtomineagainstthe
difficultyofthelastblockpresentinyourlocalcopyoftheblockchainwhichmaytakeseveral
hours.Thisisdoneviathe`datadir`parameter:
gethnetworkid=123datadir=~/.ethereum_experimentconsole`

Starting down the trail.

InordertodomostactionsinEthereumyouneedether,andtogetit,youwillneedtogeneratean
address(see
herefordetaileddocumentationonmanagingyouraccounts
).Type:

admin.newAccount()

Youllbeaskedforapassphrase.Chooseonewiselyandyouwillbepromptedtotypeittwice.Do
NOTforgetthispassphrase,otherwiseitwillnotbepossibletorecoveranyfundsyoumayhaveon
youraccount.Youvebeenwarned!

Tip:
Typingadminbyitselfwillbringupalistofsubcommandsusedtoadministeryourgeth
installation.

TheFollowingcommandgeneratesanaddressandassociatesitwithyourlocalmachine.Youcan
createmultipleaccountsbyexecutingthesamecommandagain.Goon,tryit:

admin.newAccount()

Byconventionwecallthefirstaccountyoucreateyourprimaryaccount.Youcanseeallyour
accountswiththecommand:

eth.accounts

NoticethatitoutputsaJavascriptarray.Itsbecauseallcommandsontheconsoleareactuallyin
javascript,soyoucancreatevariablesanddaisychainfunctions.Youcanalsowriteanyeth
functionasweb3.ethsinceitsactuallypartofthemainweb3object.

Trythisforexample:

varprimaryAccount=eth.accounts[0]

YounowhaveavariablecalledprimaryAccountthatyoucanuseinothercalls,likethis:


eth.getBalance(primaryAccount)

Alreadyfeelingcomfortable?Timetogetsomeether.Therearethreedifferentways:

1. Get ether from someone else

Thatisbyfartheeasiestwaytogetether,butyouneedtoknowsomeonewhoiswillingtogiveyou
ahand.Ifyouhavesuchafriend,thentype:

eth.accounts[0]

Copytheaddressandsendittothemhopingtoreceivesomelovethroughtheether.Ifyoudon't
knowanyonewhocanprovideitforyou,youcanuseafaucet,whichhandouttestetherforfree.
Trythe
Zerogox
or
EtherParty
faucets.Ifthefaucetsarenotonlineforsomereason,youcanalso
tryaskingdirectlytothecommunityon
IRC
.

2. Mining ether

Sinceyouareoneofthefirstpioneers,itmightbepossibletoacquireetherbymining.Youcan
startyourminingoperationbytyping

admin.miner.start()

Beforeyoucanreallyfindblocksyourcomputerneedstogothroughaprocesscalledbuildinga
DAG.TheDAG(whichstandsforDirectedAcyclicGraph)isalargeblockofdatathatisrequired
formining,intendedtopreventASICappliances(whichstandsforApplicationSpecificIntegrated
Circuits)frombeingmassmanufacturedforminingethereum.Itisintendedtoprotectpioneers
likeyourselfsothatyouwillonlyeverneedyourhomecomputertomine..TheDAGshouldtake
about10minutestogenerateandassoonasitfinishesitwillstartminingautomatically.Ifatany
pointyouwanttoseewhatsgoingon,youcantype

admin.miner.hashrate()

Thisgivesyouanideaofhowmuchworkyourcomputerisdoingpersecond.Nowheadtothe
NetworkStatsPage
andtakealookattheDifficulty.
Dividethatnumberbyyourcurrent
hashrateandthatwillgiveyouanestimate,inseconds,ofhowlongyoucanexpecttowait
untilyoumineablockandgetsomeether.
Thisisanoverestimatebecauseitdoesnottakein
considerationthenumberandrewardsforuncleblocks
.
Youcanusethiscodesnippettodothis
automatically:

Math.floor(10*eth.getBlock("latest").difficulty/(60*
admin.miner.hashrate()))/10+"Minutes"

Ifyouhavesuccessfullyminedablockyouwillseeamessagelikethisinthelogfile:

Minedblock#12345

Yourcoinbaseistheaccountwhereyourminingrewardissent,bydefaultitistheprimaryaccount.
Inordertocheckyourearnings,youcandisplayyourcoinbasebalance:

web3.fromWei(eth.getBalance(eth.coinbase),"ether")

Note:theminingrewardsinthefrontiernetworkareonly10%ofwhattheyllbewhenthe
Homesteadphasebegins.Frontiershouldbealwaysconsideredatestnetworkforthe
network.

Thingstodo:
Ifyouareseriousaboutmining,thenyoucanalso:readmoreaboutminingwith
geth,
understandthecurrentproofofwork
andwhyitisASICresistant,readupaboutproofof
stake,orstartyourGPUminingoperation.
ReadtheMiningDocumentation
orcheckoutthe
ethereumminingguide
onourforums.

3. Importing from the presale

Beforeyoudecidetoimportyourpresaleetherwallet,pleaserememberthatFrontierisatest
network.Itsdangerous,potentiallyfullofbugsandispronetoinstability.Whileallaccount
balancesabove1etherwillbemovedovertohomesteadwhenitlaunches,themoneyincontracts
willnot.Therearemanypotentialmishaps,moneycanbelost,stolenorlockedintoabroken
contract.Westronglyadviseyoutoonlymovefundsthatyouarewillingtorisk.Ifyoustillwantto
goforward,
readthisotherarticle
.[LINKNEEDED]

Sending your first transaction

Therearetwotypesofaccountsinethereum:

1. normalaccounts,whichholdonlyetherthatcanbemovedwithaprivatekeyand
2. contractaddresses,whichholdethercontrolledbyitsowninternalcode.Letsfocusonthe
formerfirst.

Andsimilarly,yourtransactionsarealsooftwotypes:transactionssenttonormalaccountsare
ethertransfers,whiletherestiscommunicationwithsmartcontracts,

Beforeyousendyourfirstethertransferyouneedafriendtosendyouretherto.Ifyoudonthave
any,youcanalsocreateasmanynewaccountsasyouwant,followingthestepsdiscussedabove
andsimplymoveyourfundsbetweenaccountsyouown.Afteryouvedonethat,runthis:

varsender=eth.accounts[0]
varreceiver=eth.accounts[1]
varamount=web3.toWei(0.01,"ether")

Thefirsttwolinessetlocalvariableswithaccountnumbersforeasieraccesslater..Changethe
senderandreceiveraddressasmuchasyoulike.Ifyouareaddinganaddressinstead,putitin
betweenquoteslike0xffd25e388bf07765e6d7a00d6ae83fa750460c7e'.Thethirdlineconvertsthe
tokenunitsasrequiredbythenetwork..

Althoughtherearemanynamesfor
etherdenominations
wewilluseonlytwo:etherandwei.
Theweiistheminimumatomicunitofether,andiswhatisusedonthesystemlevel.Mostdayto
daytransactionswillbedonewithether,whichisequivalenttoonequintillionwei,ora1followed
by18zeros.Sobeforesendinganytransactionsitsveryimportanttoconvertittowei,andforthat,
usethe
web3.toWei
function.(Ifyouaredealingwithsmallamountsofether,itmightbeusefulto
usefinney,whichisashorthandforathousandthofanether,butinmostcasesetherwillsuffice).

Afterhavingsetthevariablesabove,sendthetransactionwith:

eth.sendTransaction({from:sender,to:receiver,value:amount})

Afterwaitingafewseconds,thetransactionshouldbecomplete.Tocheckthebalanceofan
account,yousimplytype:

eth.getBalance(eth.accounts[0])

Tip:ifyouwanttocheckthebalanceofallyouraccountsatonce,usethisJavaScriptcode
snippet:

Thiscodewillrunineachofyouraccountsandprintitsbalanceinether.

functioncheckAllBalances(){
vari=0
eth.accounts.forEach(function(e){

console.log("eth.accounts["+i+"]:"+e+"\tbalance:"+
web3.fromWei(eth.getBalance(e),"ether")+"ether")

i++
})
}

Onceyouexecutedthelineabove,allyouneedtocheckyourwholebalanceis:

checkAllBalances()

Tryityourself:
tweakthisjavascriptfunctiontomakeitshowanotherunit,likefinney.

Learnmore:
Readthetransactionsdocumentation

Easier addresses: the Name Registrar

Allaccountsarereferencedinthenetworkbytheirpublicaddress.Butaddressesarelong,difficult
towritedown,hardtomemorizeandimmutable.Thelastoneisspeciallyimportantifyouwantto
beabletogeneratefreshaccountsinyourname,orupgradethecodeofyourcontract.Inorderto
solvethis,thereisadefaultnameregistrarcontractwhichisusedtoassociatethelongaddresses
withshort,humanfriendlynames.

Nameshavetouseonlyalphanumericcharactersand,cannotcontainblankspaces.Infuture
releasesthenameregistrarwilllikelyimplementabiddingprocesstopreventnamesquattingbut
fornow,it'safirstcomefirstservedbased.Soaslongasnooneelseregisteredthename,youcan
claimit.

First,selectyourname:

varmyName="bob"

Then,checktheavailabilityofyourname:
registrar.addr(myName)

Ifthatfunctionreturns"0x00..",youcanclaimittoyourself:

registrar.reserve.sendTransaction(myName,{from:eth.accounts[0]})

Waitfortheprevioustransactiontobepickedup.Waituptothirtysecondsandthentry:

registrar.owner(myName)

Ifitreturnsyouraddress,itmeansyouownthatnameandareabletosetyourchosennameto
anyaddressyouwant:


registrar.setAddress.sendTransaction(myName,eth.accounts[1],true,{from:
eth.accounts[0]})

Youcansendatransactiontoanyonebynameinsteadofaccountsimplybytyping

eth.sendTransaction({from:eth.accounts[0],to:registrar.addr("bob"),
value:web3.toWei(1,"ether")})

Tip:
don'tmistakeregistrar.addrforregistrar.owner.Thefirstistowhichaddressthatnameis
pointedat:anyonecanpointanametoanywhereelse,justlikeanyonecanforwardalinkto
google.com,butonlytheownerofthenamecanchangeandupdatethelink.Youcansetbothto
bethesameaddress.

Contracts, or how to create your own personal country

Nowthatyoumasteredthebasicsonhowtogetstartedandhowtosendether,it'stimetogetyour
handsdirtyinwhatreallymakesethereumstandoutofthecrowd:smartcontracts.Smartcontracts
arepiecesofcodethatliveontheblockchainandexecutecommandsexactlyhowtheyweretold
to.Theycanreadothercontracts,takedecisions,sendetherandexecuteothercontracts.
Contractswillexistandrunaslongasthewholenetworkexists,andwillonlystopiftheyrunoutof
gasoriftheywereprogrammedtoselfdestruct.

Whatcanyoudowithcontracts?Youcandoalmostanythingreally,butforthisguidelet'sdo
somethingsimple:youwillstartyournewcountry.

Yourcountrywon'tbeverypowerfulcomparedtomost:itwillholdnoland,havenomilitaryand
holdnoassetsotherthanthosethatexistontheblockchain.Allit'scitizenswillbevoluntaryandit
isunabletocoerceotherpeoplebyforce.

Butwhatit
can
doistogathersupportaroundaunitedcause.Youwillgetfundsthrougha
crowdfundingthat,ifsuccessful,willsupplyaradicallytransparentanddemocraticorganizationthat
willonlyobeyitsowncitizens,willneverswerveawayfromitsconstitutionandcannotbecensored
orshutdown.Andallthatinlessthan300linesofcode.

Solet'sstartnow.

Important:Frontierisconsideredatestnetwork.Allcontractsmightbewipedwhenthe
projecttransitionstothenextphase,andallethertheycontainwillbelost.Onlysendsmall
amountsoffundstocontracts,unlessareokaylosingthem.

Your first citizen: the greeter

fulldocumentation:https://github.com/ethereum/goethereum/wiki/ContractsandTransactions
NowthatyouvemasteredthebasicsofEthereum,letsmoveintoyourfirstseriouscontract.Itsa
bigopenterritoryandsometimesyoumightfeellonely,soourfirstorderofbusinesswillbeto
createalittleautomaticcompaniontogreetyouwheneveryoufeellonely.Wellcallhimthe
Greeter.

contractgreeter{
//Declarevariableadminwhichwillstoreanaddress
addresspublicadmin

//thisfunctionisexecutedatinitialization
//andsetstheownerofthecontract
functiongreeter(){
admin=msg.sender
}

//mainfunction
functiongreet(bytes32input)returns(bytes32){
if(input==""){return"Hello,World"}
returninput
}

//Functiontorecoverthefundsonthecontract
functionkill(){
if(msg.sender==admin){
suicide(admin)
}
}
}

Asyoucansee,theGreeterisanintelligentdigitalentitythatlivesontheblockchainandisableto
haveconversationswithanyonewhointeractswithit,basedonitsinput.Itmightnotbeatalker,
butitsagreatlistener.

Beforeyouareabletouploadittothenetwork,youneedtwothings:thecompiledcode,andthe
ApplicationBinaryInterface,whichisasortofuserguideonhowtointeractwiththecontract.

Thefirstyoucangetbyusingacompiler.Youshouldhaveasoliditycompilerbuiltinonyourgeth
console.Totestit,usethiscommand:

eth.getCompilers()

Ifyouhaveitinstalled,itshouldoutputsomethinglikethis:

['Solidity']

Ifinsteadthecommandreturnsanerror,thenreadthedocumentationon
howtoinstallacompiler
,
use
Alethzero
orusethe
onlinesoliditycompiler
.

IfyouhaveGethSolidityCompilerinstalled,youneednowreformatbyremovingspacessoitfits
intoastringvariable(thereare
someonlinetools
thatwilldothis):

vargreeterSource='contractgreeter{addressadminfunctiongreeter()
{admin=msg.sender}functiongreet(bytes32input)returns(bytes32){
if(input==""){return"Hello,World"}returninput}function
kill(){if(msg.sender==admin){suicide(admin)}}}'

Onceyousuccessfullyexecutedtheabove,compileitandpublishtothenetworkusingthe
followingcommands:

vargreeterCompiled=eth.compile.solidity(greeterSource)
vargreeterAddress=eth.sendTransaction({data:
greeterCompiled.greeter.code,from:eth.accounts[0],gas:1000000,
gasPrice:web3.toWei(0.001,"finney")})

Youwillprobablybeaskedforthepasswordyoupickedinthebeginning.Youarechoosingfrom
whichaccountwillpayforthetransaction.Dependingonthecurrentgasprice,expectthatthis
contracttocostapproximately
0.5ether
.

Waitaminuteforyourtransactiontobepickedupandthentype:

eth.getCode(greeterAddress)

Thisshouldreturnthecodeofyourcontract.Ifitreturns0x,itmeansthatyourtransactionhasnot
beenpickedupyet.Waitalittlebitmore.Ifitstillhasn't,checkifyouareconnectedtothenetwork

net.peerCount

Youcanalsotakealooktoseeifyourtransactionisonthelistofpendingtransactionswaitingto
bepickedup:

eth.pendingTransactions()

Ifyouhavemorethan0peersandittakesmorethanaminuteortwoforyourtransactiontobe
mined,yourgaspricemighthavebeentoolow.Gobacktothatcommandaboveandtryplaying
aroundwiththegaspriceorgasamount.Gotooupandyoumightreach
gaslimitoftheblock
,go
toolowandthepricemightbetoolow,orthegasinsufficientforthetransactiontobepickedup.

Afteryourcodehasbeenaccepted,
eth.getCode(codeAddress)
willreturnalongstringof
numbers.Ifthatsthecase,congratulations,yourlittleGreeterislive!Ifthecontractiscreated
again(byperforminganothereth.sendTransaction),itwillbepublishedtoanewaddress.

Nowthatyourcontractisliveonthenetwork,anyonecaninteractwithitbyinstantiatingalocal
copy.Butinordertodothat,yourcomputerneedstoknowhowtointeractwithit,whichiswhatthe
ApplicationBinaryInterface
(ABI)isfor.TogenerateacontractfromABIyouhavetodothis:

greeterContract=
eth.contract(greeterCompiled.greeter.info.abiDefinition)

Tip:
ifthesoliditycompilerisn'tproperlyinstalledinyourmachine,youcangettheABIfromthe
onlinecompiler
.Todoso,usethecodebelowcarefullyreplacing
greeterCompiled.greeter.info.abiDefinition
withtheabifromyourcompiler.

Afterhavingcreatedalocalcopyoftheobject,thisishowyouactuallyinstantiatethatobjectfroma
livecontractaddress:

greeterInstance=greeterContract.at(greeterAddress)

Alternatively,thosetwolinescouldbewrittentogetherinasinglecall:

greeterInstance=
eth.contract(greeterCompiled.greeter.info.abiDefinition).at(greeterAddres
s)

Yourinstanceisready.Inordertocallit,justtypethefollowingcommandinyourterminal:

greeterInstance.greet.call("")

IfyourgreeterreturnedHelloWorldthencongratulations,youjustcreatedyourfirstdigital
conversationalistbot!Tryagainwith:

greeterInstance.greet.call("hi")

Cleaningupafteryourself:
Youmustbeveryexcitedtohaveyourfirstcontractlive,butthis
excitementwearsoffsometimes,whentheownersgoontowritefurthercontracts,leadingtothe
unpleasantsightofabandonedcontractsontheblockchain.Inthefuture,blockchainrentmightbe
implementedinordertoincreasethescalabilityoftheblockchainbutfornow,beagoodcitizenand
humanelyputdownyourabandonedbots.Thesuicideissubsidizedbythecontractcreationsoit
willcostmuchlessthanausualtransaction.

greeterInstance.kill.sendTransaction({from:eth.accounts[0],gasPrice:
web3.toWei(0.001,"finney")})

Noticethateverycontracthastoimplementit'sown
killclause
.Inthisparticularcaseonlythe
accountthatcreatedthecontractcankillit.Ifyoudon'taddanykillclauseitcouldpotentiallylive
forever(oratleastuntilthefrontiercontractsareallwiped)independentlyofyouandanyearthly
borders,sobeforeyouputitlivecheckwhatyourlocallawssayaboutit,includinganypossible
limitationontechnologyexport,restrictionsonspeechandmaybefuturelegislationoncivilrightsof
sentientdigitalbeings.

Tryityourself:
Youcanexperimentchangingitsparameterstomakeitsmarter.Challenge
yourselftohaveitchargeetherforitsprofoundadvicebyaddingthefollowingfunctiononthe
"greet".Here'sasimpleexampleonhowtomakethegreeterintoajokerbymakingitselljokes*:

if(input=="Who'sthere?"){
/*insertajokehere*/
}elseif(msg.value>1000){
/*atrillionthofanether.It'sacheapjoke.*/
return"Knockknock!"
}

Anybalanceyourgreeterisabletomakewillbeforwardedtoyouonthekillcall.

*Actuallytheblockchainisopensourceandanyonecouldreadyourjokeforfree,buthasanyoneeverlaughedbyreading
sourcecode?


Testitwithothers:
anyoneelserunningthegethconsolecaninteractwithyourcontractbyfirst
instantiatingitusingthislineofcode:

greeterInstance=
eth.contract([{constant:false,inputs:[],name:'kill',outputs:[],type:'func
tion'},{constant:false,inputs:[{name:'input',type:'bytes32'}],name:'greet
',outputs:[{name:'',type:'bytes32'}],type:'function'},{inputs:[],type:'co
nstructor'}]).at(greeterAddress)

Issue your own money: Coin contract

Nowlet'screateacoinforyourcountry.Coinsaremuchmoreinterestingandusefulthanthey
seem,theyareinessencejustatradeabletoken,butcanbecomemuchmore,dependingonhow
youusethem.It'svaluedependsonit'suse:atokencanbeusedtocontrolaccess(anentrance
ticket),canbeusedforvotingrightsinanorganization(ashare),canbeplaceholdersforanasset
heldbyathirdparty(acertificateofownership)orevenbesimplyusedasanexchangeofvalue
withinacommunity(acurrency).

Youcoulddoallthosethingsbycreatingacentralizedserver,butusinganEthereumtoken
contractcomeswithsomefreequalities:forone,it'sadecentralizedserviceandtokenscanbestill
exchangedeveniftheoriginalservicegoesdownforanyreason.Thecodeguaranteesthatno
tokenswilleverbecreatedotherthantheonessetintheoriginalcode.Finally,byhavingeachuser
holdit'sowntoken,thiseliminatesthescenarioswhereonesingleserverbreakincanresultinthe
lossoffundsfromthousandsofclients.

Thisisthecodeforthecontractwe'rebuilding:

contracttoken{
mapping(address=>uint)publicbalance

/*Initializescontractwith10000tokenstothecreatorofthecontract*/
functiontoken(){
balance[msg.sender]=10000
}

/*Verysimpletradefunction*/
functionsendToken(addressreceiver,uintamount)returns(boolsufficient){
if(balance[msg.sender]<amount)returnfalse
balance[msg.sender]=amount
balance[receiver]+=amount
returntrue
}


Ifyouhaveeverprogrammed,youwon'tfindithardtounderstandwhatitdoes:it'sacontractthat
generates10thousandtokenstothecreatorofthecontract,andthenallowsanyonewithabalance
tosendittoothers.Thesetokensaretheminimumtradeableunitandcannotbesubdivided,butfor
thefinaluserscouldbepresentedasa100unitssubdividableby100subunits,soowningasingle
tokenwouldrepresenthaving0.01%ofthetotal.Ifyourapplicationneedsmorefinegrainatomic
divisibility,thenjustincreasetheinitialissuanceamount.

Inthisexamplewedeclaredthevariable"balance"tobepublic,thiswillautomaticallycreatea
functionthatchecksanyaccountsbalance.

Solet'srunit!

vartokenSource='contracttoken{mapping(address=>uint)public
balance/*Initializescontractwith10000tokenstothecreatorofthe
contract*/functiontoken(){balance[msg.sender]=10000}/*Very
simpletradefunction*/functionsendToken(addressreceiver,uint
amount)returns(boolsufficient){if(balance[msg.sender]<amount)
returnfalsebalance[msg.sender]=amountbalance[receiver]+=amount
returntrue}}'

Nowletssetupthecontract,justlikewedidintheprevioussection..

vartokenCompiled=eth.compile.solidity(tokenSource)
vartokenAddress=eth.sendTransaction({data:tokenCompiled.token.code,
from:eth.accounts[0],gas:1000000,gasPrice:web3.toWei(0.001,
"finney")})

Waitminuteuntilandusethecodebelowtotestifyourcodehasbeendeployed.

eth.getCode(tokenAddress)

Andthen

tokenInstance=
eth.contract(tokenCompiled.token.info.abiDefinition).at(tokenAddress)

Youcancheckyourownbalancewith:

tokenInstance.balance.call(eth.accounts[0])

Itshouldhaveallthe10000tokensthatwerecreatedoncethecontractwaspublished.Sincethere
isnotanyotherdefinedwayfornewcoinstobeissued,thoseareallthatwilleverexist.

Nowofcoursethosetokensaren'tveryusefulifyouhoardthemall,soinordertosendthemto
someoneelse,usethiscommand:

tokenInstance.sendToken.sendTransaction(eth.accounts[1],1000,{from:
eth.accounts[0]})

Ifafriendhasregisteredanameontheregistraryoucansenditwithoutknowingtheiraddress,
doingthis:

tokenInstance.sendToken.sendTransaction(registrar.addr("Alice"),2000,
{from:eth.accounts[0]})

Thereasonthatthefirstcommandwas.call()andthesecondisa.sendTransaction()isthatthe
formerisjustareadoperationandthelatterisusinggastochangethestateoftheblockchain,and
assuch,itneedstobesetwhoisitcomingfrom.Now,waitaminuteandcheckbothaccounts
balances:

tokenInstance.balance.call(eth.accounts[0])
tokenInstance.balance.call(eth.accounts[1])
tokenInstance.balance.call(registrar.addr("Alice"))

Tryforyourself:
Youjustcreatedyourowncryptocurrency!Rightnowthiscryptocurrencyisquite
limitedastherewillonlyeverbe10,000coinsandallarecontrolledbythecoincreator,butyoucan
changethat.Youcouldforexamplerewardethereumminers,bycreatingatransactionthatwill
rewardwhofoundthecurrentblock:

mapping(uint=>address)miningReward
functionclaimMiningReward(){
if(miningReward[block.number]==0){
balances[block.coinbase]+=1
miningReward[block.number]=block.coinbase
}
}

Youcouldmodifythistoanythingelse:mayberewardsomeonewhofindsasolutionforanew
puzzle,winsagameofchess,installasolarpanelaslongasthatcanbesomehowtranslatedto
acontract.Ormaybeyouwanttocreateacentralbankforyourpersonalcountry,soyoucankeep
trackofhoursworked,favorsowedorcontrolofproperty.Inthatcaseyoumightwanttoadda
functiontoallowthebanktoremotelyfreezefundsanddestroytokensifneeded.

Gettingotherstointeractwithyourcontract

ThecommandsmentionedonlyworkbecauseyouhavetokenInstanceinstantiatedonyourlocal
machine.Ifyousendtokenstosomeonetheywon'tbeabletomovethemforwardbecausethey
don'thavethesameobject.Infactifyourestartyourconsoletheseobjectswillbedeletedandthe
contractsyou'vebeenworkingonwillbelostforever.Sohowdoyouinstantiatethecontractona
cleanmachine?

Therearetwoways.Let'sstartwiththequickanddirty,providingyourfriendswithareferenceto
yourcontractsABI:

tokenInstance=
eth.contract([{constant:false,inputs:[{name:'receiver',type:'address'},{n
ame:'amount',type:'uint256'}],name:'sendToken',outputs:[{name:'sufficient
',type:'bool'}],type:'function'},{type:'function',constant:true,inputs:[{
name:'',type:'address'}],name:'balance',outputs:[{name:'',type:'uint256'}
]},{inputs:[],type:'constructor'}]).at('0x4a4ce7844735c4b6fc66392b200ab6f
e007cfca8')

Justreplacetheaddressattheendforyourowntokenaddress,thenanyonethatusesthissnippet
willimmediatelybeabletouseyourcontract.Ofcoursethiswillworkonlyforthisspecificcontract
solet'sanalyzestepbystepandseehowtoimprovethiscodesoyou'llbeabletouseitanywhere.

First,ifyouregisteraname,thenyouwon'tneedthehardcodedaddressintheend.Selectanice
coinnameforyouandtrytoreserveforyourself.

vartokenName="MyFirstCoin"
registrar.reserve.sendTransaction(tokenName,{from:eth.accounts[0]})

Waitfortheprevioustransactiontobepickedupandthensetthatnametopointtoyourcoin
address:

registrar.setAddress.sendTransaction(tokenName,tokenAddress,true,{from:
eth.accounts[0]})

Waitalittlebitforthattransactiontobepickeduptooandtestit:

registrar.addr("MyFirstCoin")

Thisshouldnowreturnyourtokenaddress,meaningthatnowthepreviouscodetoinstantiate
coulduseanameinsteadofanaddress.

tokenInstance=
eth.contract([{constant:false,inputs:[{name:'receiver',type:'address'},{n
ame:'amount',type:'uint256'}],name:'sendToken',outputs:[{name:'sufficient

',type:'bool'}],type:'function'},{type:'function',constant:true,inputs:[{
name:'',type:'address'}],name:'balance',outputs:[{name:'',type:'uint256'}
]},{inputs:[],type:'constructor'}]).at(registrar.addr("MyFirstCoin"))

Thisalsomeansthattheownerofthecoincanupdatethecoinbypointingtheregistrartothenew
contract.Thiswould,ofcourse,requirethecoinholderstrusttheownersetat
registrar.owner("MyFirstCoin")

Thecodeisstilllongandnotveryfriendly,andthat'smostlybecauseoftheABIthatusesmostof
thecontractcodespace.Ideallytheonlythingtheusershouldneedtoknowtoaccessthecontract
wouldbeit'sname.Inordertodothatwehavetoregistertheabisomewherealso,whichwhatthe
ContractMetadataRegistry
isfor.

Toinitiatetheprocess,executethis:

admin.contractInfo.newRegistry(eth.accounts[0])

InthefutureEthereumwillhavesupportforapurehashbasedcontentsystemtoallowanydatato
besavedintheP2Pnetwork,butfornowwe'llhavetocreatesomefilesanduploadthem
manually.Firstcreateafileonyoursystem(e.g.inyourdesktop,ifyou'remessylikeme)andadd
itspathlikethis:

varlocalFilePath='/Users/yourusername/Desktop/abi.json'

Nowusethislinetowritetothatfileandsaveitshash:

contentHash=admin.contractInfo.register(eth.accounts[0],tokenAddress,
tokenCompiled.token,localFilePath)

Younowhavetoputthe.jsonfileyoujustcreatedsomewherepubliclyaccessible.Ifyouhavean
httpserveryoucanjustdragintoit,butyoucanalsouseaservicelike
PasteBin
or
Gist
.Createa
newunlisted/privatefile,copythecontentfromthefileyoujustcreatedandsaveit.Thenclickthe
"raw"linkandgetthelinklikethis:

varremoteFilePath=
'https://gist.githubusercontent.com/alexvandesande/ee0d34f5ac47937b6330/r
aw/6813c4e5eee9af33a1728565141ca4572530ffcd/abi.json'

NowfinallyyoucanregistertheABIwith:

admin.contractInfo.registerUrl(eth.accounts[0],contentHash,
remoteFilePath)

Waitfortheminerstopickitupandcheckifeverythingwentwellwith:


admin.contractInfo.get(registrar.addr(tokenName)).AbiDefinition

ThisshouldreturntheABI.Ifitdoesn't,thendoublechecktheprocessandmaybetryuploading
yourfiletoadifferenthost.Nowinordertoinstantiatethecontractinanycomputerallonehasto
knowiseitheritsaddressorregisteredname.

vartokenAddress=registrar.addr("MyFirstCoin")
vartokenInstance=
eth.contract(admin.contractInfo.get(tokenAddress).AbiDefinition).at(token
Address)

Futureimprovements,notyetimplemented:

Formalproofing
isawaywherethecontractdeveloperwillbeabletoassertsome
invariantqualitiesofthecontract,likethetotalcapofthecoin.
Metacoinstandard
isaproposedstandardizationoffunctionnamesforcoinandtoken
contracts,toallowthemtobeautomaticallyaddedtootherethereumcontractthatutilizes
trading,likeexchangesorescrow.

Trustless fundraising: the crowdfunder


Creatingacountrytakesalotoffundsandcollectiveeffort.Youcouldaskfordonations,butdonors
prefertogivetoprojectstheyaremorecertainthatwillgettractionandproperfunding.Thisisan
examplewhereacrowdfundingwouldbeideal:yousetupagoalandadeadlineforreachingit.If
youmissyourgoal,thedonationsarereturned,thereforereducingtheriskfordonors.Sincethe
codeisopenandauditable,thereisnoneedforacentralizedtrustedplatformandthereforethe
onlyfeeseveryonewillpayarejustthegasfees.

Sinceyoualreadyhaveyourowninternalcurrency,youcanusethattohelpgatherfunds.Inthis
crowdsalecontracteveryonewhocontributewillalsogetaproportionalamountofthetokensyou
created.Thiscanbeusedtoasaproofofcitizenship,asasharesystemorsimplyasarewardfor
theirhelpasearlypioneers.

Attention:AllcontractscouldbewipedoutattheendofFrontier.Whilebalancesonnormal
addresseswillbetransportedtoHomestead,balancesincontracts,aswellasaddresses
withlessthan1ether,willnot.Sousethiscrowdfundingcontractfortestingpurposesand
don'tputanysignificantfundsunlessyouknowwhatyouaredoing.

contracttoken{
functionsendToken(addressreceiver,uint256amount)returns(boolsufficient){}
functiongetBalance(addressaccount)returns(uint256balance){}

contractCrowdSale{

addresspublicadmin
addresspublicbeneficiary
uintpublicfundingGoal
uintpublicnumFunders
uintpublicamountRaised
uintpublicdeadline
uintpublicprice
tokenpublictokenReward
mapping(uint=>Funder)publicfunders

/*datastructuretoholdinformationaboutcampaigncontributors*/
structFunder{
addressaddr
uintamount
}

/*atinitialization,setuptheowner*/
functionCrowdSale(){
admin=msg.sender
}

functionsetup(address_beneficiary,uint_fundingGoal,uint_deadline,uint_price,address
_reward)returns(bytes32response){
if(msg.sender==admin&&!(beneficiary>0&&fundingGoal>0&&deadline>0)){
beneficiary=_beneficiary
fundingGoal=_fundingGoal
deadline=_deadline
price=_price
tokenReward=token(_reward)

return"campaignisset"
}elseif(msg.sender!=admin){
return"notauthorized"
}else{
return"campaigncannotbechanged"
}
}

/*Thefunctionwithoutnameisthedefaultfunctionthatiscalledwheneveranyonesendsfunds
toacntract*/
function()returns(bytes32response){
Funderf=funders[numFunders++]
f.addr=msg.sender
f.amount=msg.value
amount+=f.amount
tokenReward.sendToken(msg.sender,f.amount/price)

return"thanksforyourcontribution"
}

/*checksifthegoalortimelimithasbeenreachedandendsthecampaign*/
functioncheckGoalReached()returns(bytes32response){
if(amountRaised>=fundingGoal){
uinti=0
beneficiary.send(amount)
suicide(beneficiary)
return"GoalReached!"
}
elseif(deadline<=block.number){
uintj=0
uintn=numFunders
while(j<=n){

funders[j].addr.send(funders[j].amount)
funders[j].addr=0
funders[j].amount=0
j++
}
suicide(beneficiary)
return"Deadlinepassed"
}
return"Notreachedyet"
}
}

Youknowthedrill.
Removelinebreaks
andcopythefollowingcommandsontheterminal:

varcrowdsaleSource='contracttoken{functionsendToken(address
receiver,uint256amount)returns(boolsufficient){}function
getBalance(addressaccount)returns(uint256balance){}}contract
CrowdSale{addresspublicadminaddresspublicbeneficiaryuintpublic
fundingGoaluintpublicnumFundersuintpublicamountRaiseduint
publicdeadlineuintpublicpricetokenpublictokenRewardmapping
(uint=>Funder)publicfunders/*datastructuretoholdinformation
aboutcampaigncontributors*/structFunder{addressaddruintamount
}/*atinitialization,setuptheowner*/functionCrowdSale(){admin=
msg.sender}functionsetup(address_beneficiary,uint_fundingGoal,
uint_deadline,uint_price,address_reward)returns(bytes32response){
if(msg.sender==admin&&!(beneficiary>0&&fundingGoal>0&&
deadline>0)){beneficiary=_beneficiaryfundingGoal=_fundingGoal
deadline=_deadlineprice=_pricetokenReward=token(_reward)
return"campaignisset"}elseif(msg.sender!=admin){return"not
authorized"}else{return"campaigncannotbechanged"}}/*The
functionwithoutnameisthedefaultfunctionthatiscalledwhenever
anyonesendsfundstoacntract*/function()returns(bytes32response)
{Funderf=funders[numFunders++]f.addr=msg.senderf.amount=
msg.valueamount+=f.amounttokenReward.sendToken(msg.sender,
f.amount/price)return"thanksforyourcontribution"}/*checksif
thegoalortimelimithasbeenreachedandendsthecampaign*/function
checkGoalReached()returns(bytes32response){if(amountRaised>=
fundingGoal){uinti=0beneficiary.send(amount)suicide(beneficiary)
return"GoalReached!"}elseif(deadline<=block.number){uintj=0
uintn=numFunderswhile(j<=n){
funders[j].addr.send(funders[j].amount)funders[j].addr=0
funders[j].amount=0j++}suicide(beneficiary)return"Deadline
passed"}return"Notreachedyet"}}'

varcrowdsaleCompiled=eth.compile.solidity(crowdsaleSource)
varcrowdsaleAddress=eth.sendTransaction({data:
crowdsaleCompiled.CrowdSale.code,from:eth.accounts[0],gas:1000000,
gasPrice:web3.toWei(0.001,"finney")})

Waitminuteuntilandusethecodebelowtotestifyourcodehasbeendeployed.

eth.getCode(crowdsaleAddress)

Ifithas,thendothesecommandstoinstantiateitlocally.

crowdsaleInstance=
web3.eth.contract(crowdsaleCompiled.CrowdSale.info.abiDefinition).at(crow
dsaleAddress)

Yourfirststepnowistosetthecontractup.Youcanonlydoitonceanditneedstocomefromthe
sameaccountthatcreatedthecontractinthefirstplace.

varbeneficiary=eth.accounts[1] //createanaccountforthis
varfundingGoal=web3.toWei(100,"ether")//raisesa100ether
vardeadline=eth.blockNumber+200000//aboutfourweeks
varprice=web3.toWei(0.02,"ether")//thepriceofthetokens,in
ether
varreward=registrar.addr("MyFirstCoin")
//thetokencontract
address.

OnBeneficiaryputthenewaddressthatwillreceivetheraisedfunds.Thefundinggoalisthe
amountofethertoberaised.Deadlineismeasuredinblocktimeswhichaverage12seconds,so
thedefaultisabout4weeks.Thepriceistricky:butjustchangethenumber2fortheamountof
tokensthecontributorswillreceiveforeachetherdonated.Finallyrewardshouldbetheaddressof
thetokencontractyoucreatedinthelastsection.

Inthisexampleyouaresendingtothecrowdsalefund50%ofallthetokensthateverexisted,in
exchangefor100ether.Decidethoseparametersverycarefullyastheywillplayaveryimportant
roleonthenextpartofourguide.

crowdsaleInstance.setup.sendTransaction(beneficiary,fundingGoal,deadline,price,reward,{from:
eth.accounts[0],gas:150000,gasPrice:web3.toWei(0.001,"finney")})

Dontforgettofundyournewlycreatedcontractwiththenecessarytokenssoitcanpaybackthe
contributors!

tokenInstance.sendToken.sendTransaction(crowdsaleAddress,5000,{from:eth.accounts[0]})

Afterthetransactionispicked,youcanchecktheamountoftokensthecrowdsaleaddresshas,
andallothervariablesthisway:

tokenInstance.balance.call(crowdsaleAddress)

crowdsaleInstance.beneficiary.call()
crowdsaleInstance.amountRaised.call()
crowdsaleInstance.fundingGoal.call()

Youarenowset.Anyonecannowcontributebyfollowingthesesteps.First,sendthemthecode
addressyoujustcreated.Nowanyonecansimplyfollowthesesteps:

crowdsaleInstance=
eth.contract([{inputs:[],name:'checkGoalReached',outputs:[{name:'response',type:'bytes32'}],type:'f
unction',constant:false},{inputs:[],name:'deadline',outputs:[{name:'',type:'uint256'}],type:'functi
on',constant:true},{inputs:[],name:'beneficiary',outputs:[{name:'',type:'address'}],type:'function'
,constant:true},{outputs:[{name:'response',type:'bytes32'}],type:'function',constant:false,inputs:[
{name:'_beneficiary',type:'address'},{name:'_fundingGoal',type:'uint256'},{name:'_deadline',type:'u
int256'},{name:'_price',type:'uint256'},{name:'_reward',type:'address'}],name:'setup'},{constant:tr
ue,inputs:[],name:'tokenReward',outputs:[{name:'',type:'address'}],type:'function'},{constant:true,
inputs:[],name:'fundingGoal',outputs:[{type:'uint256',name:''}],type:'function'},{inputs:[],name:'p
rice',outputs:[{type:'uint256',name:''}],type:'function',constant:true},{constant:true,inputs:[],na
me:'amountRaised',outputs:[{name:'',type:'uint256'}],type:'function'},{constant:true,inputs:[],name
:'numFunders',outputs:[{name:'',type:'uint256'}],type:'function'},{inputs:[{name:'',type:'uint256'}
],name:'funders',outputs:[{name:'addr',type:'address'},{name:'amount',type:'uint256'}],type:'functi
on',constant:true},{inputs:[],name:'admin',outputs:[{name:'',type:'address'}],type:'function',const
ant:true},{inputs:[],type:'constructor'}]).at(crowdsaleAddress)

var
crowdsaleAddress="0x000000"//important,addheretheaddressofyour

varamount=web3.toWei(4,"ether")//decidehowmuchtocontribute
eth.sendTransaction({from:eth.accounts[0],to:crowdsaleAddress,value:
amount,gas:1000000,gasPrice:web3.toWei(0.001,"finney")})

crowdsaleInstance.sendTransaction({from:eth.accounts[0],value:amount,
gas:1000000,gasPrice:web3.toWei(0.001,"finney")})

Nowwaitaminutefortheblockstopickupandyoucancheckifthecontractreceivedtheetherby
doingthis:

eth.getBalance(crowdsaleAddress)

Ifthebalancehaschanged,usenowthistocheckifyoureceivedtokens

tokenInstance.balance.call(eth.accounts[0])

Oncethedeadlineispassedsomeonehastowakeupthecontracttohavethefundssenttoeither
thebeneficiaryorbacktothefunders(ifitfailed).Thishappensbecausethereisnosuchthingas
anactivelooportimeronethereumsoanyfuturetransactionsmustbepingedbysomeone.

crowdsaleInstance.checkGoalReached.sendTransaction({from:eth.accounts[1],
gas:1000000,gasPrice:web3.toWei(0.001,"finney")})

Registeringyourcontract

Inorderforyourcontracttobeaccessiblebyotherpeopleyouhavetodoabitmorework.First,
pickanameforyourcrowdsale:

varname="mycrowdsale"

Checkifthat'savailableandregister:

registrar.addr(name)
registrar.reserve.sendTransaction(name,{from:eth.accounts[0]})

Waitfortheprevioustransactiontobepickedupandthen:

registrar.setAddress.sendTransaction(name,crowdsaleAddress,true,{from:
eth.accounts[0]})

Anyonecanaccessthecrowdsaleby:

crowdsaleInstance=
eth.contract([{constant:false,inputs:[],name:'checkGoalReached',outputs:[
{name:'response',type:'bytes32'}],type:'function'},{constant:false,inputs
:[{name:'_beneficiary',type:'address'},{name:'_fundingGoal',type:'uint256
'},{type:'uint256',name:'_deadline'},{name:'_price',type:'uint256'},{name
:'_reward',type:'address'}],name:'setup',outputs:[{name:'response',type:'
bytes32'}],type:'function'},{type:'function',constant:false,inputs:[],nam
e:'contribute',outputs:[{name:'response',type:'bytes32'}]},{inputs:[],typ
e:'constructor'}]).at(registrar.addr('mycrowdsale')

OptionallyyoucanmakethisshorterbysavingtheABIonaURL.Createablankfilecalledabi.json
inyourdesktopandthenexecutethis:

admin.contractInfo.newRegistry(eth.accounts[0])

contentHash=admin.contractInfo.register(eth.accounts[0],
crowdsaleAddress,crowdsaleCompiled.CrowdSale,
'/Users/yourusername/Desktop/abi.json')

Uploadthefiletoaserverorsimplypastethecontenton
PasteBin
or
Gist
.Createanew
unlisted/privatefile,copythecontentfromthefileyoujustcreatedandsaveit.Click"raw"andput
thelinkonthisnextcommand:


admin.contractInfo.registerUrl(eth.accounts[0],contentHash,
'https://YOURADDRESS/abi.json')

Waitfortheminerstopickitupandcheckifeverythingwentwellwith:

admin.contractInfo.get(registrar.addr(name))

Ifthisdoesn'treturnanerror,thenit'sready.Nowinordertoinstantiatethecontractinany
computerallonehastoknowiseitheritsaddressorregisteredname.

vartokenAddress=registrar.addr("MyFirstCoin")
vartokenInstance=
eth.contract(admin.contractInfo.get(tokenAddress).AbiDefinition).at(token
Address)

A decentralized autonomous organization: the Democracy Contract


Sofaryoucreatedatradeabletokenandyousuccessfullydistributeditamongallthosewhowere
willingtohelpfundraisea100ethers.That'sallveryinterestingbutwhatexactlyarethosetokens
for?Whywouldanyonewanttoownortradeitforanythingelsevaluable?Ifyoucanconvince
yournewtokenisthenextbigmoneymaybeotherswillwantit,butsofaryourtokenoffersno
valueperse.Wearegoingtochangethat,bycreatingyourfirstdecentralizedautonomous
organization,orDAO.

ThinkoftheDAOastheconstitutionofyourcountry,theexecutivebranchofit'sgovernmentor
maybelikeacompletelyroboticmiddlemanagerforanorganization.TheDAOreceivesthemoney
thatyourorganizationraisesviaanymeans,keepsitsafeandusesittofundwhateverit'scitizens
want.Therobotisincorruptible,itwillneverdefraudthebank,nevercreatesecretplans,neveruse
themoneyforanythingotherthanwhatit'sconstituentsvotedon.TheDAOwillneverdisappear,
neverrunawayandcannotbecontrolledbyanyoneotherthanit'sowncitizens.

Thetokenwecreatedusingthecrowdsaleistheonlycitizendocumentneeded.Anyonewhoholds
anytokenisabletocreateandvoteonproposals.Similartobeingashareholderinacompany,the
tokencanbetradedontheopenmarketandthevoteisproportionaltoamountsoftokensthevoter
holds.

Takeamomenttodreamabouttherevolutionarypossibilitiesthiswouldallow,andnowyoucando
ityourself,inundera100linesofcode:


contracttoken{functionsendToken(addressreceiver,uint256amount)returns(boolsufficient){}
functiongetBalance(addressaccount)returns(uint256balance){}}

contractDemocracy{

uintconstantminimumQuorum=100
uintconstantdebatingPeriod=7days
tokenvoterShare
uintnumProposals=0
addressfounder

mapping(uint=>Proposal)proposals

structProposal{
addressrecipient
uintamount
bytes32descriptionHash
uintcreationDate
uintnumVotes
uintquorum
boolactive
mapping(uint=>Vote)votes
mapping(address=>bool)voted
}

structVote{
intposition
addressvoter
}

functionDemocracy(){
founder=msg.sender
}

functionsetup(address_voterShareAddress){
if(msg.sender==founder&&numProposals==0){
voterShare=token(_voterShareAddress)
}

functionnewProposal(address_recipient,uint_amount,bytes32_descriptionHash)returns
(uintproposalID){
if(voterShare.getBalance(msg.sender)>0){
proposalID=numProposals++
Proposalp=proposals[proposalID]
p.recipient=_recipient
p.amount=_amount
p.descriptionHash=_descriptionHash
p.creationDate=now
p.numVotes=0

p.active=true
}else{
return0
}
}

functiongetProposalsCount()returns(uintcount){
returnnumProposals
}

functiongetProposalRecipient(uint_proposalID)returns(addressrecipient){
returnproposals[_proposalID].recipient
}

functiongetProposalAmount(uint_proposalID)returns(uintamount){
returnproposals[_proposalID].amount
}

functionvote(uint_proposalID,int_position)returns(uintvoteID){
if(voterShare.getBalance(msg.sender)>0&&(_position>=1||_position<=1)){
Proposalp=proposals[_proposalID]
if(!p.voted[msg.sender]){
voteID=p.numVotes++
Votev=p.votes[voteID]
v.position=_position
v.voter=msg.sender
p.voted[msg.sender]=true
}
}else{
return0
}
}

functionexecuteProposal(uint_proposalID)returns(uintresult){
Proposalp=proposals[_proposalID]
//Checkifdebatingperiodisover
if(now>p.creationDate+debatingPeriod&&p.active){

uintyea=0
uintnay=0
//tallythevotes
for(uinti=0i<=p.numVotesi++){
Votev=p.votes[i]
uintvoteWeight=voterShare.getBalance(v.voter)
p.quorum+=voteWeight

if(v.position>0){
yea+=voteWeight
}if(v.position<0){
nay+=voteWeight
}
}
//executeresult
if(p.quorum>minimumQuorum&&yea>nay){
p.recipient.send(p.amount)
p.active=false
}elseif(p.quorum>minimumQuorum&&nay>yea){
p.active=false
}
returnyeanay
}
}
}

There'salotofgoingonbutifyouhaveeverreadanykindofcodethisoneshouldbeeasily
understandable.Therulesofyourcountryareverysimple:anyonewithatleastonetokencan
createproposalstosendfundsfromthecountry'saccount.Afteraweekofdebateandvotes,ifit
hasreceivedvotestotallyatleast100tokensandhasmoreapprovalsthanrejections,thefunds
willbesent.Ifthequorumhasn'tbeenmetoritendsonatie,thenvotingiskeptuntilit'sresolved.
Otherwise,theproposalislockedandkeptforhistoricalpurposes.

Solet'srecapwhatthismeans:inthelasttwosectionsyoucreated10,000tokens,sent1,000of
thosetoanotheraccountyoucontrol,2,000toafriendnamedAliceanddistributed5,000ofthem
viaacrowdsale.Thismeansthatyounolongercontrolover50%ofthevotesintheDAO,andif

Aliceandthecommunitybandstogether,theycanoutvoteanyspendingdecisiononthe100ethers
raisedsofar.Thisisexactlyhowademocracyshouldwork.Ifyoudon'twanttobeapartofyour
countryanymoretheonlythingyoucandoissellyourowntokensonadecentralizedexchange
andoptout,butyoucannotpreventtheothersfromdoingso.

Soopenyourconsoleandlet'sgetreadytofinallyputyourcountryonline:

vardaoSource='contracttoken{functionsendToken(address
receiver,uint256amount)returns(boolsufficient){}function
getBalance(addressaccount)returns(uint256balance){}}contract
Democracy{uintconstantminimumQuorum=100uintconstant
debatingPeriod=7daystokenvoterShareuintnumProposals=0address
foundermapping(uint=>Proposal)proposalsstructProposal{address
recipientuintamountbytes32descriptionHashuintcreationDateuint
numVotesuintquorumboolactivemapping(uint=>Vote)votesmapping
(address=>bool)voted}structVote{intpositionaddressvoter}
functionDemocracy(){founder=msg.sender}functionsetup(address
_voterShareAddress){if(msg.sender==founder&&numProposals==0){
voterShare=token(_voterShareAddress)}}functionnewProposal(address
_recipient,uint_amount,bytes32_descriptionHash)returns(uint
proposalID){if(voterShare.getBalance(msg.sender)>0){proposalID=
numProposals++Proposalp=proposals[proposalID]p.recipient=
_recipientp.amount=_amountp.descriptionHash=_descriptionHash
p.creationDate=nowp.numVotes=0p.active=true}else{return0
}}functiongetProposalsCount()returns(uintcount){return
numProposals}functiongetProposalRecipient(uint_proposalID)returns
(addressrecipient){returnproposals[_proposalID].recipient}function
getProposalAmount(uint_proposalID)returns(uintamount){return
proposals[_proposalID].amount}functionvote(uint_proposalID,int
_position)returns(uintvoteID){if(voterShare.getBalance(msg.sender)>0
&&(_position>=1||_position<=1)){Proposalp=
proposals[_proposalID]if(!p.voted[msg.sender]){voteID=
p.numVotes++Votev=p.votes[voteID]v.position=_positionv.voter=
msg.senderp.voted[msg.sender]=true}}else{return0}}function
executeProposal(uint_proposalID)returns(uintresult){Proposalp=
proposals[_proposalID]if(now>p.creationDate+debatingPeriod&&
p.active){uintyea=0uintnay=0for(uinti=0i<=p.numVotes
i++){Votev=p.votes[i]uintvoteWeight=
voterShare.getBalance(v.voter)p.quorum+=voteWeightif(v.position>
0){yea+=voteWeight}if(v.position<0){nay+=voteWeight}}if
(p.quorum>minimumQuorum&&yea>nay){p.recipient.send(p.amount)
p.active=false}elseif(p.quorum>minimumQuorum&&nay>yea){
p.active=false}returnyeanay}}}'

vardaoCompiled=eth.compile.solidity(daoSource)

vardaoAddress=eth.sendTransaction({data:daoCompiled.Democracy.code,
from:eth.accounts[0],gas:1000000,gasPrice:web3.toWei(0.001,
"finney")})

Waitaminuteuntiltheminerspickitup.Itwillcostyouabout0.6ethersincurrentmarketprice.
Onceit'spickedupit'stimetoinstantiateitandsetitup,bypointingittothecorrectaddressofthe
tokencontractyoucreatedpreviously.Let'salsoregisteranameforyourcontractsoit'seasily
accessible(don'tforgettocheckyournameavailabilitywith
registrar.addr("nameYouWant")
beforereserving!)

varname="MyPersonalCountry"
registrar.reserve.sendTransaction(name,{from:eth.accounts[0]})
vardaoInstance=
eth.contract(daoCompiled.Democracy.info.abiDefinition).at(daoAddress)
daoInstance.setup.sendTransaction(registrar.addr("MyFirstCoin"),{from:eth
.accounts[0]})
daoInstance.getProposalCount.call()

Waitfortheprevioustransactionstobepickedupandthen:

registrar.setAddress.sendTransaction(name,daoAddress,true,{from:
eth.accounts[0]})

IfeverythingissetupthenyourDAOshouldreturnaproposalcountof0,showingithasno
proposalsyet.Whiletheproposalcountis0,thefounderoftheDAOcanchangetheaddressofthe
tokentoanythingitwants.Afteryouaresatisfiedwithwhatyouwant,it'stimetogetallthatether
yougotfromthecrowdfundingandintoyournewcountry:

eth.sendTransaction({from:eth.accounts[1],to:daoAddress,value:
web3.toWei(100,"ether")})

Thisshouldtakeonlyaminuteandyourcountryisreadyforbusiness!Now,asafirstpriority,your
countryneedsaniceflag,butunlessyouareaflagexpert,youhavenoideahowtodothat.For
thesakeofargumentlet'ssayyoufindthatyourfriendBobisagreatflagdesignerwho'swillingto
doitforonly10ethers,soyouwanttoproposetohirehimtodesignaflag.

recipient=registrar.addr("bob")
amount=web3.toWei(10,"ether")
shortNote="FlagDesign"
daoInstance.newProposal.sendTransaction(recipient,amount,shortNote,
{from:eth.accounts[0],gas:1000000,gasPrice:web3.toWei(0.001,
"finney")})

Afteraminute,anyonecanchecktheproposalrecipientandamountbyexecutingthese
commands:


daoInstance.getProposalRecipient.call(0)
daoInstance.getProposalAmount.call(0)

Unlikemostgovernments,yourcountry'sgovernmentiscompletelytransparentandeasily
programmable.Asasmalldemonstrationhere'sasnippetofcodethatgoesthroughallthecurrent
proposalsandprintswhattheyareandforwhom:

functioncheckAllProposals(){
for(i=0i<daoInstance.getProposalsCount.call()i++){
console.log("Proposal#"+i+"
Send"+web3.fromWei(
daoInstance.getProposalAmount.call(i),"ether")+"ethertoaddress"+
daoInstance.getProposalRecipient.call(i))
}
}
checkAllProposals()

Aconcernedcitizencouldeasilywriteabotthatperiodicallypingstheblockchainandthen
publicizesanynewproposalsthatwereputforth,guaranteeingtotaltransparency.

Nowofcourseyouwantotherpeopletobeabletovoteonyourproposals.Youcancheckthe
crowdsaletutorialonthebestwaytoregisteryourcontractappsothatalltheuserneedsisa
name,butfornowlet'susetheeasierversion.Anyoneshouldbeabletoinstantiatealocalcopyof
yourcountryintheircomputerbyusingthisgiantcommand:

daoInstance=
eth.contract([{constant:false,inputs:[{name:'_proposalID',type:'uint256'}
],name:'executeProposal',outputs:[{name:'result',type:'uint256'}],type:'f
unction'},{constant:false,inputs:[{name:'_proposalID',type:'uint256'}],na
me:'getProposalAmount',outputs:[{name:'amount',type:'uint256'}],type:'fun
ction'},{constant:false,inputs:[{name:'_proposalID',type:'uint256'},{name
:'_position',type:'int256'}],name:'vote',outputs:[{name:'voteID',type:'ui
nt256'}],type:'function'},{type:'function',constant:false,inputs:[{name:'
_voterShareAddress',type:'address'}],name:'setup',outputs:[]},{constant:f
alse,inputs:[],name:'getProposalsCount',outputs:[{name:'count',type:'uint
256'}],type:'function'},{inputs:[{name:'_recipient',type:'address'},{name
:'_amount',type:'uint256'},{name:'_descriptionHash',type:'bytes32'}],name
:'newProposal',outputs:[{name:'proposalID',type:'uint256'}],type:'functio
n',constant:false},{type:'function',constant:false,inputs:[{type:'uint256
',name:'_proposalID'}],name:'getProposalRecipient',outputs:[{name:'recipi
ent',type:'address'}]},{type:'constructor',inputs:[]}]).at(registrar.addr
('MyPersonalCountry'))

Thenanyonewhoownsanyofyourtokenscanvoteontheproposalsbydoingthis:


varproposalID=0
varposition=1//+1forvotingyea,1forvotingnay,0abstainsbut
countsasquorum
daoInstance.vote.sendTransaction(proposalID,position,{from:
eth.accounts[0]})

Unlessyouchangedthebasicparametersinthecode,anyproposalwillhavetobedebatedforat
leastaweekuntilitcanbeexecuted.Afterthatanyoneevenanoncitizencandemandthe
votestobecountedandtheproposaltobeexecute.Thevotesaretalliedandweightedatthat
momentandiftheproposalisacceptedthentheetherissentimmediatelyandtheproposal.Ifthe
votesendinatieortheminimumquorumhasntbeenreached,thevotingiskeptopenuntilthe
stalemateisresolved.Ifitloses,thenit'sarchivedandcannotbevotedagain.

varproposalID=0
daoInstance.executeProposal.sendTransaction(proposalID,{from:
eth.accounts[0]})

IftheproposalpassedthenyoushouldbeabletoseeBob'sethersarrivingonhisaddress:

eth.getBalance(registrar.addr("bob"))

Tryforyourself:
Thisisaverysimpledemocracycontract,whichcouldbevastlyimproved:
currently,allproposalshavethesamedebatingtimeandarewonbydirectvoteandsimple
majority.Canyouchangethatsoitwillhavesomesituations,dependingontheamountproposed,
thatthedebatemightbelongerorthatitwouldrequirealargermajority?Alsothinkaboutsome
waywherecitizensdidn'tneedtovoteoneveryissueandcouldtemporarilydelegatetheirvotesto
aspecialrepresentative.Youmighthavealsonoticedthatweaddedatinydescriptionforeach
proposal.Thiscouldbeusedasatitlefortheproposalorcouldbeahashofalargerdocument
describingitindetail.

Let's go exploring!

Youhavereachedtheendofthistutorial,butit'sjustthebeginningofagreatadventure.Lookback
andseehowmuchyouaccomplished:youcreatedaliving,talkingrobot,yourowncryptocurrency,
raisedfundsthroughatrustlesscrowdfundingandusedittokickstartyourownpersonalcountry.

Forthesakeofsimplicity,thesimpledemocraticorganizationyoucreatedcanonlysendether
around,thenativecurrencyofethereum.Whilethatmightbegoodenoughforsome,thisisonly

scratchingthesurfaceofwhatcanbedone.Intheethereumnetworkcontractshaveallthesame
rightsasanynormaluser,meaningthatyourorganizationcouldbeprogrammedinsuchwaythatit
coulddoanyofthetransactionsthatyouexecutedcomingfromyourownaccounts.

Whatcouldhappennext?

Thegreetercontractyoucreatedatthebeginningcouldbeimprovedtochargeetherforits
servicesandcouldfunnelthosefundsintotheDAO.
Thetokensyoustillcontrolcouldbesoldonadecentralizedexchangeortradedforgoods
andservicestofundfurtherdevelopthefirstcontractandgrowtheorganization.
YourDAOcouldownit'sownnameonthenameregistrar,andthenchangewhereit's
redirectinginordertoupdateitselfifthetokenholdersapproved.
Theorganizationcouldholdnotonlyethers,butanykindofothercoincreatedonethereum,
includingassetswhosevaluearetiedtothebitcoinordollar.
TheDAOcouldbeprogrammedtoallowaproposalwithmultipletransactions,some
scheduledtothefuture.
ItcouldalsoownsharesofotherDAO's,meaningitcouldvoteonlargerorganizationorbe
apartofafederationofDAO's
TheTokenContractcouldbereprogrammedtoholdetherortoholdothertokensand
distributeittothetokenholders,linkingthereforethevalueofthetokentothevalueofother
assets,sopayingdividendscouldbeaccomplishedbysimplymovingfundstothetoken
address

Thisallmeansthatthistinysocietyyoucreatedcouldgrow,getfundingfromthirdparties,pay
recurrentsalaries,ownanykindofcryptoassetsandevenusecrowdsalestofunditsactivities.All
withfulltransparency,completeaccountabilityandcompleteimmunityfromanyhuman
interference.Whilethenetworklivesthecontractswillexecuteexactlythecodetheywerecreated
toexecute,withoutanyexception,forever.

Sowhatwillyourcontractbe?Willitbeacountry,acompany,anonprofitgroup?Whatwillyour
codedo?

That'suptoyou.

More stuff to do
Youaccomplishedalottoday,youshouldfeelproud.Butifyouarestillthirstyforknowledge,here
aresomecoolprojectsthatareliveandyoucanparticipatein:

Etherex
Augur
eDollar
Redditflairmanager(suggestion:basiccontractwhereuserscanrequestfrontierflairsin
thesubreddit)
etc..

More references

https://github.com/ethereum/wiki/wiki/SolidityTutorial
https://dappsforbeginners.wordpress.com/tutorials/contractsthatsendtransactions/

You might also like