32
Gething started Welcome to the Frontier! The Frontier is the first live release of the Ethereum network. As such you are entering uncharted territory and you are invited to test the grounds and explore. There is a lot of danger, there may still be undiscovered traps, there may be ravaging bands of pirates waiting to attack you, but there also is vast room for opportunities. In order to navigate the Frontier, you’ll need to use the command line. If you are not comfortable using it, we strongly advise you to step back, watch from a distance for a while and wait until more user friendly tools are made available. Remember, there are no safety nets and for everything you do here, you are mostly on your own. Hitching up your wagon.

Frontier Documentation

  • Upload
    jlehto

  • View
    53

  • Download
    6

Embed Size (px)

DESCRIPTION

tutorial for ethereum testnet

Citation preview

  • Gething started

    Welcome to the Frontier! TheFrontieristhefirstlivereleaseoftheEthereumnetwork.Assuchyouareenteringunchartedterritoryandyouareinvitedtotestthegroundsandexplore.Thereisalotofdanger,theremaystillbeundiscoveredtraps,theremayberavagingbandsofpirateswaitingtoattackyou,buttherealsoisvastroomforopportunities.InordertonavigatetheFrontier,youllneedtousethecommandline.Ifyouarenotcomfortableusingit,westronglyadviseyoutostepback,watchfromadistanceforawhileandwaituntilmoreuserfriendlytoolsaremadeavailable.Remember,therearenosafetynetsandforeverythingyoudohere,youaremostlyonyourown.

    Hitching up your wagon.

  • TheFrontiertooliscalledGeth(theoldenglishthirdpersonsingularconjugationoftogo.QuiteappropriategivengethiswritteninGo).Inordertogetit,openyourcommandlinetool(ifyouareunsurehowtodothis,considerwaitingforamoreuserfriendlyrelease)andpastethecommandbelow.rubye"$(curlfsSLhttps://raw.githubusercontent.com/cubedro/frontier.ethereum.org/master/bin/install.rb)"

    Or,alternativelyrubye"$(curlfsSLhttps://raw.githubusercontent.com/cubedro/frontier.ethereum.org/master/bin/install.rb)"Pastetheaboveonelinerinyourterminalforanautomatedinstallscript.ThisscriptwilldetectyourOSandwillattempttoinstalltheethereumCLI.Pleaseclickthebuttonbelowifyou'dliketoseeastepbystepdescriptionoftheinstallerscript.GethisamultipurposecommandlinetoolthatrunsafullEthereumnodeimplementedinGo.Itoffersthreeinterfaces:thecommandlinesubcommandsandoptions[link],aJSONRPCserverandaninteractiveconsole.Forthepurposesofthisguide,wewillfocusontheConsole,ajavascriptenvironmentthatcontainsallthemainfeaturesyouprobablywant.Typethecodebelowonyourterminalgethconsole2>>geth.logYouarereadytostart.The2>>geth.logcreatesatextfilewiththeoutputofyourconsole.OnalinuxmachineorMacOSyoucanrunoneterminalwiththegethconsoleandasecondonewiththeloggingoutputbyopeninganewterminalandtyping:ttyTheoutputwillbesomethinglike:/dev/pts/13(oronMac/dev/tty002).Theninyourmainterminaltype:gethconsole2>>/dev/pts/13Thiswillallowyoutomonitoryournodewithoutclutteringyourconsole.Thegethconsolehashistorythatpersistsbetweensessions.Youcannavigateyourcommandhistorybyusingtheupanddownarrowkeys.Tip:sometimesyoumightnotneedtoconnecttothelivepublicnetwork,youcaninsteadchoosetocreateyourownprivatetestnet.Thisisveryusefulifyoudon'tneedtotestexternalcontractsandwantjusttotestthetechnology,becauseyouwon'thavetocompetewithotherminersandwilleasilygeneratealotoftestethertoplayaround(replace12345withanynumbergethnetworkid12345console

  • Ifyouuseaprivatetestnet,itmaybeagoodideatostartwitha'fresh'blockchain,andnottherealblockchain.Otherwise,inordertosuccessfullymineablock,you'llneedtomineagainstthedifficultyofthelastblockpresentinyourlocalcopyoftheblockchainwhichmaytakeseveralhours.Thisisdoneviathe`datadir`parameter: gethnetworkid=123datadir=~/.ethereum_experimentconsole`

    Starting down the trail. InordertodomostactionsinEthereumyouneedether,andtogetit,youwillneedtogenerateanaddress(seeherefordetaileddocumentationonmanagingyouraccounts).Type:admin.newAccount()Youllbeaskedforapassphrase.Chooseonewiselyandyouwillbepromptedtotypeittwice.DoNOTforgetthispassphrase,otherwiseitwillnotbepossibletorecoveranyfundsyoumayhaveonyouraccount.Youvebeenwarned!Tip:Typingadminbyitselfwillbringupalistofsubcommandsusedtoadministeryourgethinstallation.TheFollowingcommandgeneratesanaddressandassociatesitwithyourlocalmachine.Youcancreatemultipleaccountsbyexecutingthesamecommandagain.Goon,tryit:admin.newAccount()Byconventionwecallthefirstaccountyoucreateyourprimaryaccount.Youcanseeallyouraccountswiththecommand:eth.accountsNoticethatitoutputsaJavascriptarray.Itsbecauseallcommandsontheconsoleareactuallyinjavascript,soyoucancreatevariablesanddaisychainfunctions.Youcanalsowriteanyethfunctionasweb3.ethsinceitsactuallypartofthemainweb3object.Trythisforexample:varprimaryAccount=eth.accounts[0]YounowhaveavariablecalledprimaryAccountthatyoucanuseinothercalls,likethis:

  • eth.getBalance(primaryAccount)Alreadyfeelingcomfortable?Timetogetsomeether.Therearethreedifferentways:

    1. Get ether from someone else Thatisbyfartheeasiestwaytogetether,butyouneedtoknowsomeonewhoiswillingtogiveyouahand.Ifyouhavesuchafriend,thentype:eth.accounts[0]Copytheaddressandsendittothemhopingtoreceivesomelovethroughtheether.Ifyoudon'tknowanyonewhocanprovideitforyou,youcanuseafaucet,whichhandouttestetherforfree.TrytheZerogoxorEtherPartyfaucets.Ifthefaucetsarenotonlineforsomereason,youcanalsotryaskingdirectlytothecommunityonIRC.

    2. Mining ether Sinceyouareoneofthefirstpioneers,itmightbepossibletoacquireetherbymining.Youcanstartyourminingoperationbytypingadmin.miner.start()BeforeyoucanreallyfindblocksyourcomputerneedstogothroughaprocesscalledbuildingaDAG.TheDAG(whichstandsforDirectedAcyclicGraph)isalargeblockofdatathatisrequiredformining,intendedtopreventASICappliances(whichstandsforApplicationSpecificIntegratedCircuits)frombeingmassmanufacturedforminingethereum.Itisintendedtoprotectpioneerslikeyourselfsothatyouwillonlyeverneedyourhomecomputertomine..TheDAGshouldtakeabout10minutestogenerateandassoonasitfinishesitwillstartminingautomatically.Ifatanypointyouwanttoseewhatsgoingon,youcantypeadmin.miner.hashrate()Thisgivesyouanideaofhowmuchworkyourcomputerisdoingpersecond.NowheadtotheNetworkStatsPageandtakealookattheDifficulty.Dividethatnumberbyyourcurrenthashrateandthatwillgiveyouanestimate,inseconds,ofhowlongyoucanexpecttowaituntilyoumineablockandgetsomeether.Thisisanoverestimatebecauseitdoesnottakeinconsiderationthenumberandrewardsforuncleblocks.Youcanusethiscodesnippettodothisautomatically:

  • Math.floor(10*eth.getBlock("latest").difficulty/(60*admin.miner.hashrate()))/10+"Minutes"Ifyouhavesuccessfullyminedablockyouwillseeamessagelikethisinthelogfile:Minedblock#12345Yourcoinbaseistheaccountwhereyourminingrewardissent,bydefaultitistheprimaryaccount.Inordertocheckyourearnings,youcandisplayyourcoinbasebalance:web3.fromWei(eth.getBalance(eth.coinbase),"ether")Note:theminingrewardsinthefrontiernetworkareonly10%ofwhattheyllbewhentheHomesteadphasebegins.Frontiershouldbealwaysconsideredatestnetworkforthenetwork.Thingstodo:Ifyouareseriousaboutmining,thenyoucanalso:readmoreaboutminingwithgeth,understandthecurrentproofofworkandwhyitisASICresistant,readupaboutproofofstake,orstartyourGPUminingoperation.ReadtheMiningDocumentationorcheckouttheethereumminingguideonourforums.

    3. Importing from the presale Beforeyoudecidetoimportyourpresaleetherwallet,pleaserememberthatFrontierisatestnetwork.Itsdangerous,potentiallyfullofbugsandispronetoinstability.Whileallaccountbalancesabove1etherwillbemovedovertohomesteadwhenitlaunches,themoneyincontractswillnot.Therearemanypotentialmishaps,moneycanbelost,stolenorlockedintoabrokencontract.Westronglyadviseyoutoonlymovefundsthatyouarewillingtorisk.Ifyoustillwanttogoforward,readthisotherarticle.[LINKNEEDED]

    Sending your first transaction Therearetwotypesofaccountsinethereum:

    1. normalaccounts,whichholdonlyetherthatcanbemovedwithaprivatekeyand2. contractaddresses,whichholdethercontrolledbyitsowninternalcode.Letsfocusonthe

    formerfirst.

  • Andsimilarly,yourtransactionsarealsooftwotypes:transactionssenttonormalaccountsareethertransfers,whiletherestiscommunicationwithsmartcontracts,Beforeyousendyourfirstethertransferyouneedafriendtosendyouretherto.Ifyoudonthaveany,youcanalsocreateasmanynewaccountsasyouwant,followingthestepsdiscussedaboveandsimplymoveyourfundsbetweenaccountsyouown.Afteryouvedonethat,runthis: varsender=eth.accounts[0]varreceiver=eth.accounts[1]varamount=web3.toWei(0.01,"ether")Thefirsttwolinessetlocalvariableswithaccountnumbersforeasieraccesslater..Changethesenderandreceiveraddressasmuchasyoulike.Ifyouareaddinganaddressinstead,putitinbetweenquoteslike0xffd25e388bf07765e6d7a00d6ae83fa750460c7e'.Thethirdlineconvertsthetokenunitsasrequiredbythenetwork..Althoughtherearemanynamesforetherdenominationswewilluseonlytwo:etherandwei.Theweiistheminimumatomicunitofether,andiswhatisusedonthesystemlevel.Mostdaytodaytransactionswillbedonewithether,whichisequivalenttoonequintillionwei,ora1followedby18zeros.Sobeforesendinganytransactionsitsveryimportanttoconvertittowei,andforthat,usetheweb3.toWeifunction.(Ifyouaredealingwithsmallamountsofether,itmightbeusefultousefinney,whichisashorthandforathousandthofanether,butinmostcasesetherwillsuffice).Afterhavingsetthevariablesabove,sendthetransactionwith:eth.sendTransaction({from:sender,to:receiver,value:amount})Afterwaitingafewseconds,thetransactionshouldbecomplete.Tocheckthebalanceofanaccount,yousimplytype:eth.getBalance(eth.accounts[0])Tip:ifyouwanttocheckthebalanceofallyouraccountsatonce,usethisJavaScriptcodesnippet:Thiscodewillrunineachofyouraccountsandprintitsbalanceinether.functioncheckAllBalances(){vari=0eth.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,difficulttowritedown,hardtomemorizeandimmutable.Thelastoneisspeciallyimportantifyouwanttobeabletogeneratefreshaccountsinyourname,orupgradethecodeofyourcontract.Inordertosolvethis,thereisadefaultnameregistrarcontractwhichisusedtoassociatethelongaddresseswithshort,humanfriendlynames.Nameshavetouseonlyalphanumericcharactersand,cannotcontainblankspaces.Infuturereleasesthenameregistrarwilllikelyimplementabiddingprocesstopreventnamesquattingbutfornow,it'safirstcomefirstservedbased.Soaslongasnooneelseregisteredthename,youcanclaimit.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,itmeansyouownthatnameandareabletosetyourchosennametoanyaddressyouwant:

  • registrar.setAddress.sendTransaction(myName,eth.accounts[1],true,{from:eth.accounts[0]})Youcansendatransactiontoanyonebynameinsteadofaccountsimplybytypingeth.sendTransaction({from:eth.accounts[0],to:registrar.addr("bob"),value:web3.toWei(1,"ether")})Tip:don'tmistakeregistrar.addrforregistrar.owner.Thefirstistowhichaddressthatnameispointedat:anyonecanpointanametoanywhereelse,justlikeanyonecanforwardalinktogoogle.com,butonlytheownerofthenamecanchangeandupdatethelink.Youcansetbothtobethesameaddress.

    Contracts, or how to create your own personal countryNowthatyoumasteredthebasicsonhowtogetstartedandhowtosendether,it'stimetogetyourhandsdirtyinwhatreallymakesethereumstandoutofthecrowd:smartcontracts.Smartcontractsarepiecesofcodethatliveontheblockchainandexecutecommandsexactlyhowtheyweretoldto.Theycanreadothercontracts,takedecisions,sendetherandexecuteothercontracts.Contractswillexistandrunaslongasthewholenetworkexists,andwillonlystopiftheyrunoutofgasoriftheywereprogrammedtoselfdestruct.Whatcanyoudowithcontracts?Youcandoalmostanythingreally,butforthisguidelet'sdosomethingsimple:youwillstartyournewcountry.Yourcountrywon'tbeverypowerfulcomparedtomost:itwillholdnoland,havenomilitaryandholdnoassetsotherthanthosethatexistontheblockchain.Allit'scitizenswillbevoluntaryanditisunabletocoerceotherpeoplebyforce.Butwhatitcandoistogathersupportaroundaunitedcause.Youwillgetfundsthroughacrowdfundingthat,ifsuccessful,willsupplyaradicallytransparentanddemocraticorganizationthatwillonlyobeyitsowncitizens,willneverswerveawayfromitsconstitutionandcannotbecensoredorshutdown.Andallthatinlessthan300linesofcode.Solet'sstartnow.

  • Important:Frontierisconsideredatestnetwork.Allcontractsmightbewipedwhentheprojecttransitionstothenextphase,andallethertheycontainwillbelost.Onlysendsmallamountsoffundstocontracts,unlessareokaylosingthem.

    Your first citizen: the greeter fulldocumentation:https://github.com/ethereum/goethereum/wiki/ContractsandTransactions NowthatyouvemasteredthebasicsofEthereum,letsmoveintoyourfirstseriouscontract.Itsabigopenterritoryandsometimesyoumightfeellonely,soourfirstorderofbusinesswillbetocreatealittleautomaticcompaniontogreetyouwheneveryoufeellonely.WellcallhimtheGreeter.contractgreeter{//Declarevariableadminwhichwillstoreanaddressaddresspublicadmin//thisfunctionisexecutedatinitialization//andsetstheownerofthecontractfunctiongreeter(){admin=msg.sender}//mainfunctionfunctiongreet(bytes32input)returns(bytes32){if(input==""){return"Hello,World"}returninput} //Functiontorecoverthefundsonthecontractfunctionkill(){if(msg.sender==admin){suicide(admin)}}}

  • Asyoucansee,theGreeterisanintelligentdigitalentitythatlivesontheblockchainandisabletohaveconversationswithanyonewhointeractswithit,basedonitsinput.Itmightnotbeatalker,butitsagreatlistener.Beforeyouareabletouploadittothenetwork,youneedtwothings:thecompiledcode,andtheApplicationBinaryInterface,whichisasortofuserguideonhowtointeractwiththecontract.Thefirstyoucangetbyusingacompiler.Youshouldhaveasoliditycompilerbuiltinonyourgethconsole.Totestit,usethiscommand:eth.getCompilers()Ifyouhaveitinstalled,itshouldoutputsomethinglikethis:['Solidity']Ifinsteadthecommandreturnsanerror,thenreadthedocumentationonhowtoinstallacompiler,useAlethzeroorusetheonlinesoliditycompiler.IfyouhaveGethSolidityCompilerinstalled,youneednowreformatbyremovingspacessoitfitsintoastringvariable(therearesomeonlinetoolsthatwilldothis):vargreeterSource='contractgreeter{addressadminfunctiongreeter(){admin=msg.sender}functiongreet(bytes32input)returns(bytes32){if(input==""){return"Hello,World"}returninput}functionkill(){if(msg.sender==admin){suicide(admin)}}}'Onceyousuccessfullyexecutedtheabove,compileitandpublishtothenetworkusingthefollowingcommands: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.Youarechoosingfromwhichaccountwillpayforthetransaction.Dependingonthecurrentgasprice,expectthatthiscontracttocostapproximately0.5ether.Waitaminuteforyourtransactiontobepickedupandthentype:

  • eth.getCode(greeterAddress)Thisshouldreturnthecodeofyourcontract.Ifitreturns0x,itmeansthatyourtransactionhasnotbeenpickedupyet.Waitalittlebitmore.Ifitstillhasn't,checkifyouareconnectedtothenetworknet.peerCountYoucanalsotakealooktoseeifyourtransactionisonthelistofpendingtransactionswaitingtobepickedup:eth.pendingTransactions()Ifyouhavemorethan0peersandittakesmorethanaminuteortwoforyourtransactiontobemined,yourgaspricemighthavebeentoolow.Gobacktothatcommandaboveandtryplayingaroundwiththegaspriceorgasamount.Gotooupandyoumightreachgaslimitoftheblock,gotoolowandthepricemightbetoolow,orthegasinsufficientforthetransactiontobepickedup.Afteryourcodehasbeenaccepted,eth.getCode(codeAddress)willreturnalongstringofnumbers.Ifthatsthecase,congratulations,yourlittleGreeterislive!Ifthecontractiscreatedagain(byperforminganothereth.sendTransaction),itwillbepublishedtoanewaddress.Nowthatyourcontractisliveonthenetwork,anyonecaninteractwithitbyinstantiatingalocalcopy.Butinordertodothat,yourcomputerneedstoknowhowtointeractwithit,whichiswhattheApplicationBinaryInterface(ABI)isfor.TogenerateacontractfromABIyouhavetodothis:greeterContract=eth.contract(greeterCompiled.greeter.info.abiDefinition)Tip:ifthesoliditycompilerisn'tproperlyinstalledinyourmachine,youcangettheABIfromtheonlinecompiler.Todoso,usethecodebelowcarefullyreplacinggreeterCompiled.greeter.info.abiDefinitionwiththeabifromyourcompiler.Afterhavingcreatedalocalcopyoftheobject,thisishowyouactuallyinstantiatethatobjectfromalivecontractaddress:greeterInstance=greeterContract.at(greeterAddress)Alternatively,thosetwolinescouldbewrittentogetherinasinglecall:greeterInstance=eth.contract(greeterCompiled.greeter.info.abiDefinition).at(greeterAddress)

  • Yourinstanceisready.Inordertocallit,justtypethefollowingcommandinyourterminal:greeterInstance.greet.call("")IfyourgreeterreturnedHelloWorldthencongratulations,youjustcreatedyourfirstdigitalconversationalistbot!Tryagainwith:greeterInstance.greet.call("hi")Cleaningupafteryourself:Youmustbeveryexcitedtohaveyourfirstcontractlive,butthisexcitementwearsoffsometimes,whentheownersgoontowritefurthercontracts,leadingtotheunpleasantsightofabandonedcontractsontheblockchain.Inthefuture,blockchainrentmightbeimplementedinordertoincreasethescalabilityoftheblockchainbutfornow,beagoodcitizenandhumanelyputdownyourabandonedbots.Thesuicideissubsidizedbythecontractcreationsoitwillcostmuchlessthanausualtransaction.greeterInstance.kill.sendTransaction({from:eth.accounts[0],gasPrice:web3.toWei(0.001,"finney")})Noticethateverycontracthastoimplementit'sownkillclause.Inthisparticularcaseonlytheaccountthatcreatedthecontractcankillit.Ifyoudon'taddanykillclauseitcouldpotentiallyliveforever(oratleastuntilthefrontiercontractsareallwiped)independentlyofyouandanyearthlyborders,sobeforeyouputitlivecheckwhatyourlocallawssayaboutit,includinganypossiblelimitationontechnologyexport,restrictionsonspeechandmaybefuturelegislationoncivilrightsofsentientdigitalbeings.Tryityourself:Youcanexperimentchangingitsparameterstomakeitsmarter.Challengeyourselftohaveitchargeetherforitsprofoundadvicebyaddingthefollowingfunctiononthe"greet".Here'sasimpleexampleonhowtomakethegreeterintoajokerbymakingitselljokes*:if(input=="Who'sthere?"){

    /*insertajokehere*/}elseif(msg.value>1000){

    /*atrillionthofanether.It'sacheapjoke.*/return"Knockknock!"

    }Anybalanceyourgreeterisabletomakewillbeforwardedtoyouonthekillcall.*Actuallytheblockchainisopensourceandanyonecouldreadyourjokeforfree,buthasanyoneeverlaughedbyreadingsourcecode?

  • Testitwithothers:anyoneelserunningthegethconsolecaninteractwithyourcontractbyfirstinstantiatingitusingthislineofcode:greeterInstance=eth.contract([{constant:false,inputs:[],name:'kill',outputs:[],type:'function'},{constant:false,inputs:[{name:'input',type:'bytes32'}],name:'greet',outputs:[{name:'',type:'bytes32'}],type:'function'},{inputs:[],type:'constructor'}]).at(greeterAddress)

    Issue your own money: Coin contract Nowlet'screateacoinforyourcountry.Coinsaremuchmoreinterestingandusefulthantheyseem,theyareinessencejustatradeabletoken,butcanbecomemuchmore,dependingonhowyouusethem.It'svaluedependsonit'suse:atokencanbeusedtocontrolaccess(anentranceticket),canbeusedforvotingrightsinanorganization(ashare),canbeplaceholdersforanassetheldbyathirdparty(acertificateofownership)orevenbesimplyusedasanexchangeofvaluewithinacommunity(acurrency).Youcoulddoallthosethingsbycreatingacentralizedserver,butusinganEthereumtokencontractcomeswithsomefreequalities:forone,it'sadecentralizedserviceandtokenscanbestillexchangedeveniftheoriginalservicegoesdownforanyreason.Thecodeguaranteesthatnotokenswilleverbecreatedotherthantheonessetintheoriginalcode.Finally,byhavingeachuserholdit'sowntoken,thiseliminatesthescenarioswhereonesingleserverbreakincanresultinthelossoffundsfromthousandsofclients.Thisisthecodeforthecontractwe'rebuilding:contracttoken{mapping(address=>uint)publicbalance

    /*Initializescontractwith10000tokenstothecreatorofthecontract*/functiontoken(){balance[msg.sender]=10000} /*Verysimpletradefunction*/functionsendToken(addressreceiver,uintamount)returns(boolsufficient){if(balance[msg.sender]

  • Ifyouhaveeverprogrammed,youwon'tfindithardtounderstandwhatitdoes:it'sacontractthatgenerates10thousandtokenstothecreatorofthecontract,andthenallowsanyonewithabalancetosendittoothers.Thesetokensaretheminimumtradeableunitandcannotbesubdivided,butforthefinaluserscouldbepresentedasa100unitssubdividableby100subunits,soowningasingletokenwouldrepresenthaving0.01%ofthetotal.Ifyourapplicationneedsmorefinegrainatomicdivisibility,thenjustincreasetheinitialissuanceamount.Inthisexamplewedeclaredthevariable"balance"tobepublic,thiswillautomaticallycreateafunctionthatchecksanyaccountsbalance.Solet'srunit!vartokenSource='contracttoken{mapping(address=>uint)publicbalance/*Initializescontractwith10000tokenstothecreatorofthecontract*/functiontoken(){balance[msg.sender]=10000}/*Verysimpletradefunction*/functionsendToken(addressreceiver,uintamount)returns(boolsufficient){if(balance[msg.sender]
  • Nowofcoursethosetokensaren'tveryusefulifyouhoardthemall,soinordertosendthemtosomeoneelse,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()isthattheformerisjustareadoperationandthelatterisusinggastochangethestateoftheblockchain,andassuch,itneedstobesetwhoisitcomingfrom.Now,waitaminuteandcheckbothaccountsbalances:tokenInstance.balance.call(eth.accounts[0])tokenInstance.balance.call(eth.accounts[1])tokenInstance.balance.call(registrar.addr("Alice"))Tryforyourself:Youjustcreatedyourowncryptocurrency!Rightnowthiscryptocurrencyisquitelimitedastherewillonlyeverbe10,000coinsandallarecontrolledbythecoincreator,butyoucanchangethat.Youcouldforexamplerewardethereumminers,bycreatingatransactionthatwillrewardwhofoundthecurrentblock:mapping(uint=>address)miningRewardfunctionclaimMiningReward(){

    if(miningReward[block.number]==0){balances[block.coinbase]+=1miningReward[block.number]=block.coinbase

    }}Youcouldmodifythistoanythingelse:mayberewardsomeonewhofindsasolutionforanewpuzzle,winsagameofchess,installasolarpanelaslongasthatcanbesomehowtranslatedtoacontract.Ormaybeyouwanttocreateacentralbankforyourpersonalcountry,soyoucankeeptrackofhoursworked,favorsowedorcontrolofproperty.Inthatcaseyoumightwanttoaddafunctiontoallowthebanktoremotelyfreezefundsanddestroytokensifneeded.

  • GettingotherstointeractwithyourcontractThecommandsmentionedonlyworkbecauseyouhavetokenInstanceinstantiatedonyourlocalmachine.Ifyousendtokenstosomeonetheywon'tbeabletomovethemforwardbecausetheydon'thavethesameobject.Infactifyourestartyourconsoletheseobjectswillbedeletedandthecontractsyou'vebeenworkingonwillbelostforever.Sohowdoyouinstantiatethecontractonacleanmachine?Therearetwoways.Let'sstartwiththequickanddirty,providingyourfriendswithareferencetoyourcontractsABI:tokenInstance=eth.contract([{constant:false,inputs:[{name:'receiver',type:'address'},{name:'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('0x4a4ce7844735c4b6fc66392b200ab6fe007cfca8')Justreplacetheaddressattheendforyourowntokenaddress,thenanyonethatusesthissnippetwillimmediatelybeabletouseyourcontract.Ofcoursethiswillworkonlyforthisspecificcontractsolet'sanalyzestepbystepandseehowtoimprovethiscodesoyou'llbeabletouseitanywhere.First,ifyouregisteraname,thenyouwon'tneedthehardcodedaddressintheend.Selectanicecoinnameforyouandtrytoreserveforyourself.vartokenName="MyFirstCoin"registrar.reserve.sendTransaction(tokenName,{from:eth.accounts[0]})Waitfortheprevioustransactiontobepickedupandthensetthatnametopointtoyourcoinaddress:registrar.setAddress.sendTransaction(tokenName,tokenAddress,true,{from:eth.accounts[0]})Waitalittlebitforthattransactiontobepickeduptooandtestit:registrar.addr("MyFirstCoin")Thisshouldnowreturnyourtokenaddress,meaningthatnowthepreviouscodetoinstantiatecoulduseanameinsteadofanaddress.tokenInstance=eth.contract([{constant:false,inputs:[{name:'receiver',type:'address'},{name:'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"))Thisalsomeansthattheownerofthecoincanupdatethecoinbypointingtheregistrartothenewcontract.Thiswould,ofcourse,requirethecoinholderstrusttheownersetatregistrar.owner("MyFirstCoin")Thecodeisstilllongandnotveryfriendly,andthat'smostlybecauseoftheABIthatusesmostofthecontractcodespace.Ideallytheonlythingtheusershouldneedtoknowtoaccessthecontractwouldbeit'sname.Inordertodothatwehavetoregistertheabisomewherealso,whichwhattheContractMetadataRegistryisfor.Toinitiatetheprocess,executethis:admin.contractInfo.newRegistry(eth.accounts[0])InthefutureEthereumwillhavesupportforapurehashbasedcontentsystemtoallowanydatatobesavedintheP2Pnetwork,butfornowwe'llhavetocreatesomefilesanduploadthemmanually.Firstcreateafileonyoursystem(e.g.inyourdesktop,ifyou'remessylikeme)andadditspathlikethis:varlocalFilePath='/Users/yourusername/Desktop/abi.json'Nowusethislinetowritetothatfileandsaveitshash:contentHash=admin.contractInfo.register(eth.accounts[0],tokenAddress,tokenCompiled.token,localFilePath)Younowhavetoputthe.jsonfileyoujustcreatedsomewherepubliclyaccessible.Ifyouhaveanhttpserveryoucanjustdragintoit,butyoucanalsouseaservicelikePasteBinorGist.Createanewunlisted/privatefile,copythecontentfromthefileyoujustcreatedandsaveit.Thenclickthe"raw"linkandgetthelinklikethis:varremoteFilePath='https://gist.githubusercontent.com/alexvandesande/ee0d34f5ac47937b6330/raw/6813c4e5eee9af33a1728565141ca4572530ffcd/abi.json'NowfinallyyoucanregistertheABIwith:admin.contractInfo.registerUrl(eth.accounts[0],contentHash,remoteFilePath)Waitfortheminerstopickitupandcheckifeverythingwentwellwith:

  • admin.contractInfo.get(registrar.addr(tokenName)).AbiDefinitionThisshouldreturntheABI.Ifitdoesn't,thendoublechecktheprocessandmaybetryuploadingyourfiletoadifferenthost.Nowinordertoinstantiatethecontractinanycomputerallonehastoknowiseitheritsaddressorregisteredname.vartokenAddress=registrar.addr("MyFirstCoin")vartokenInstance=eth.contract(admin.contractInfo.get(tokenAddress).AbiDefinition).at(tokenAddress)Futureimprovements,notyetimplemented:

    Formalproofingisawaywherethecontractdeveloperwillbeabletoassertsomeinvariantqualitiesofthecontract,likethetotalcapofthecoin.

    Metacoinstandardisaproposedstandardizationoffunctionnamesforcoinandtokencontracts,toallowthemtobeautomaticallyaddedtootherethereumcontractthatutilizestrading,likeexchangesorescrow.

    Trustless fundraising: the crowdfunder Creatingacountrytakesalotoffundsandcollectiveeffort.Youcouldaskfordonations,butdonorsprefertogivetoprojectstheyaremorecertainthatwillgettractionandproperfunding.Thisisanexamplewhereacrowdfundingwouldbeideal:yousetupagoalandadeadlineforreachingit.Ifyoumissyourgoal,thedonationsarereturned,thereforereducingtheriskfordonors.Sincethecodeisopenandauditable,thereisnoneedforacentralizedtrustedplatformandthereforetheonlyfeeseveryonewillpayarejustthegasfees.Sinceyoualreadyhaveyourowninternalcurrency,youcanusethattohelpgatherfunds.Inthiscrowdsalecontracteveryonewhocontributewillalsogetaproportionalamountofthetokensyoucreated.Thiscanbeusedtoasaproofofcitizenship,asasharesystemorsimplyasarewardfortheirhelpasearlypioneers.Attention:AllcontractscouldbewipedoutattheendofFrontier.WhilebalancesonnormaladdresseswillbetransportedtoHomestead,balancesincontracts,aswellasaddresseswithlessthan1ether,willnot.Sousethiscrowdfundingcontractfortestingpurposesanddon'tputanysignificantfundsunlessyouknowwhatyouaredoing.contracttoken{functionsendToken(addressreceiver,uint256amount)returns(boolsufficient){}functiongetBalance(addressaccount)returns(uint256balance){}

  • }contractCrowdSale{ addresspublicadminaddresspublicbeneficiaryuintpublicfundingGoaluintpublicnumFundersuintpublicamountRaiseduintpublicdeadlineuintpublicpricetokenpublictokenReward mapping(uint=>Funder)publicfunders /*datastructuretoholdinformationaboutcampaigncontributors*/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=_fundingGoaldeadline=_deadlineprice=_pricetokenReward=token(_reward) return"campaignisset"}elseif(msg.sender!=admin){return"notauthorized"}else{return"campaigncannotbechanged"}} /*Thefunctionwithoutnameisthedefaultfunctionthatiscalledwheneveranyonesendsfundstoacntract*/function()returns(bytes32response){Funderf=funders[numFunders++]f.addr=msg.senderf.amount=msg.valueamount+=f.amounttokenReward.sendToken(msg.sender,f.amount/price) return"thanksforyourcontribution"} /*checksifthegoalortimelimithasbeenreachedandendsthecampaign*/functioncheckGoalReached()returns(bytes32response){if(amountRaised>=fundingGoal){uinti=0beneficiary.send(amount)suicide(beneficiary)return"GoalReached!"}elseif(deadline
  • funders[j].addr.send(funders[j].amount)funders[j].addr=0funders[j].amount=0j++}suicide(beneficiary)return"Deadlinepassed"}return"Notreachedyet"}}Youknowthedrill.Removelinebreaksandcopythefollowingcommandsontheterminal:varcrowdsaleSource='contracttoken{functionsendToken(addressreceiver,uint256amount)returns(boolsufficient){}functiongetBalance(addressaccount)returns(uint256balance){}}contractCrowdSale{addresspublicadminaddresspublicbeneficiaryuintpublicfundingGoaluintpublicnumFundersuintpublicamountRaiseduintpublicdeadlineuintpublicpricetokenpublictokenRewardmapping(uint=>Funder)publicfunders/*datastructuretoholdinformationaboutcampaigncontributors*/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=_fundingGoaldeadline=_deadlineprice=_pricetokenReward=token(_reward)return"campaignisset"}elseif(msg.sender!=admin){return"notauthorized"}else{return"campaigncannotbechanged"}}/*Thefunctionwithoutnameisthedefaultfunctionthatiscalledwheneveranyonesendsfundstoacntract*/function()returns(bytes32response){Funderf=funders[numFunders++]f.addr=msg.senderf.amount=msg.valueamount+=f.amounttokenReward.sendToken(msg.sender,f.amount/price)return"thanksforyourcontribution"}/*checksifthegoalortimelimithasbeenreachedandendsthecampaign*/functioncheckGoalReached()returns(bytes32response){if(amountRaised>=fundingGoal){uinti=0beneficiary.send(amount)suicide(beneficiary)return"GoalReached!"}elseif(deadline
  • Waitminuteuntilandusethecodebelowtotestifyourcodehasbeendeployed.eth.getCode(crowdsaleAddress)Ifithas,thendothesecommandstoinstantiateitlocally.crowdsaleInstance=web3.eth.contract(crowdsaleCompiled.CrowdSale.info.abiDefinition).at(crowdsaleAddress)Yourfirststepnowistosetthecontractup.Youcanonlydoitonceanditneedstocomefromthesameaccountthatcreatedthecontractinthefirstplace.varbeneficiary=eth.accounts[1] //createanaccountforthisvarfundingGoal=web3.toWei(100,"ether")//raisesa100ethervardeadline=eth.blockNumber+200000//aboutfourweeksvarprice=web3.toWei(0.02,"ether")//thepriceofthetokens,inethervarreward=registrar.addr("MyFirstCoin") //thetokencontractaddress.OnBeneficiaryputthenewaddressthatwillreceivetheraisedfunds.Thefundinggoalistheamountofethertoberaised.Deadlineismeasuredinblocktimeswhichaverage12seconds,sothedefaultisabout4weeks.Thepriceistricky:butjustchangethenumber2fortheamountoftokensthecontributorswillreceiveforeachetherdonated.Finallyrewardshouldbetheaddressofthetokencontractyoucreatedinthelastsection.Inthisexampleyouaresendingtothecrowdsalefund50%ofallthetokensthateverexisted,inexchangefor100ether.Decidethoseparametersverycarefullyastheywillplayaveryimportantroleonthenextpartofourguide.crowdsaleInstance.setup.sendTransaction(beneficiary,fundingGoal,deadline,price,reward,{from:eth.accounts[0],gas:150000,gasPrice:web3.toWei(0.001,"finney")})Dontforgettofundyournewlycreatedcontractwiththenecessarytokenssoitcanpaybackthecontributors!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,sendthemthecodeaddressyoujustcreated.Nowanyonecansimplyfollowthesesteps:crowdsaleInstance=eth.contract([{inputs:[],name:'checkGoalReached',outputs:[{name:'response',type:'bytes32'}],type:'function',constant:false},{inputs:[],name:'deadline',outputs:[{name:'',type:'uint256'}],type:'function',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:'uint256'},{name:'_price',type:'uint256'},{name:'_reward',type:'address'}],name:'setup'},{constant:true,inputs:[],name:'tokenReward',outputs:[{name:'',type:'address'}],type:'function'},{constant:true,inputs:[],name:'fundingGoal',outputs:[{type:'uint256',name:''}],type:'function'},{inputs:[],name:'price',outputs:[{type:'uint256',name:''}],type:'function',constant:true},{constant:true,inputs:[],name:'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:'function',constant:true},{inputs:[],name:'admin',outputs:[{name:'',type:'address'}],type:'function',constant:true},{inputs:[],type:'constructor'}]).at(crowdsaleAddress)varcrowdsaleAddress="0x000000"//important,addheretheaddressofyourvaramount=web3.toWei(4,"ether")//decidehowmuchtocontributeeth.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")})Nowwaitaminutefortheblockstopickupandyoucancheckifthecontractreceivedtheetherbydoingthis:eth.getBalance(crowdsaleAddress)Ifthebalancehaschanged,usenowthistocheckifyoureceivedtokenstokenInstance.balance.call(eth.accounts[0])Oncethedeadlineispassedsomeonehastowakeupthecontracttohavethefundssenttoeitherthebeneficiaryorbacktothefunders(ifitfailed).Thishappensbecausethereisnosuchthingasanactivelooportimeronethereumsoanyfuturetransactionsmustbepingedbysomeone.crowdsaleInstance.checkGoalReached.sendTransaction({from:eth.accounts[1],gas:1000000,gasPrice:web3.toWei(0.001,"finney")})

  • RegisteringyourcontractInorderforyourcontracttobeaccessiblebyotherpeopleyouhavetodoabitmorework.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:[],name:'contribute',outputs:[{name:'response',type:'bytes32'}]},{inputs:[],type:'constructor'}]).at(registrar.addr('mycrowdsale')OptionallyyoucanmakethisshorterbysavingtheABIonaURL.Createablankfilecalledabi.jsoninyourdesktopandthenexecutethis:admin.contractInfo.newRegistry(eth.accounts[0])contentHash=admin.contractInfo.register(eth.accounts[0],crowdsaleAddress,crowdsaleCompiled.CrowdSale,'/Users/yourusername/Desktop/abi.json')UploadthefiletoaserverorsimplypastethecontentonPasteBinorGist.Createanewunlisted/privatefile,copythecontentfromthefileyoujustcreatedandsaveit.Click"raw"andputthelinkonthisnextcommand:

  • admin.contractInfo.registerUrl(eth.accounts[0],contentHash,'https://YOURADDRESS/abi.json')Waitfortheminerstopickitupandcheckifeverythingwentwellwith:admin.contractInfo.get(registrar.addr(name))Ifthisdoesn'treturnanerror,thenit'sready.Nowinordertoinstantiatethecontractinanycomputerallonehastoknowiseitheritsaddressorregisteredname.vartokenAddress=registrar.addr("MyFirstCoin")vartokenInstance=eth.contract(admin.contractInfo.get(tokenAddress).AbiDefinition).at(tokenAddress)

    A decentralized autonomous organization: the Democracy Contract Sofaryoucreatedatradeabletokenandyousuccessfullydistributeditamongallthosewhowerewillingtohelpfundraisea100ethers.That'sallveryinterestingbutwhatexactlyarethosetokensfor?Whywouldanyonewanttoownortradeitforanythingelsevaluable?Ifyoucanconvinceyournewtokenisthenextbigmoneymaybeotherswillwantit,butsofaryourtokenoffersnovalueperse.Wearegoingtochangethat,bycreatingyourfirstdecentralizedautonomousorganization,orDAO.ThinkoftheDAOastheconstitutionofyourcountry,theexecutivebranchofit'sgovernmentormaybelikeacompletelyroboticmiddlemanagerforanorganization.TheDAOreceivesthemoneythatyourorganizationraisesviaanymeans,keepsitsafeandusesittofundwhateverit'scitizenswant.Therobotisincorruptible,itwillneverdefraudthebank,nevercreatesecretplans,neverusethemoneyforanythingotherthanwhatit'sconstituentsvotedon.TheDAOwillneverdisappear,neverrunawayandcannotbecontrolledbyanyoneotherthanit'sowncitizens.Thetokenwecreatedusingthecrowdsaleistheonlycitizendocumentneeded.Anyonewhoholdsanytokenisabletocreateandvoteonproposals.Similartobeingashareholderinacompany,thetokencanbetradedontheopenmarketandthevoteisproportionaltoamountsoftokensthevoterholds. Takeamomenttodreamabouttherevolutionarypossibilitiesthiswouldallow,andnowyoucandoityourself,inundera100linesofcode:

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

    uintconstantminimumQuorum=100uintconstantdebatingPeriod=7daystokenvoterShareuintnumProposals=0addressfoundermapping(uint=>Proposal)proposals

    structProposal{

    addressrecipientuintamountbytes32descriptionHashuintcreationDateuintnumVotesuintquorumboolactivemapping(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

    (uintproposalID){if(voterShare.getBalance(msg.sender)>0){

    proposalID=numProposals++Proposalp=proposals[proposalID]p.recipient=_recipientp.amount=_amountp.descriptionHash=_descriptionHashp.creationDate=nowp.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||_positionp.creationDate+debatingPeriod&&p.active){

    uintyea=0uintnay=0//tallythevotesfor(uinti=0i0){

    yea+=voteWeight}if(v.positionminimumQuorum&&yea>nay){

    p.recipient.send(p.amount)p.active=false

    }elseif(p.quorum>minimumQuorum&&nay>yea){p.active=false

    }returnyeanay

    }}

    }There'salotofgoingonbutifyouhaveeverreadanykindofcodethisoneshouldbeeasilyunderstandable.Therulesofyourcountryareverysimple:anyonewithatleastonetokencancreateproposalstosendfundsfromthecountry'saccount.Afteraweekofdebateandvotes,ifithasreceivedvotestotallyatleast100tokensandhasmoreapprovalsthanrejections,thefundswillbesent.Ifthequorumhasn'tbeenmetoritendsonatie,thenvotingiskeptuntilit'sresolved.Otherwise,theproposalislockedandkeptforhistoricalpurposes.Solet'srecapwhatthismeans:inthelasttwosectionsyoucreated10,000tokens,sent1,000ofthosetoanotheraccountyoucontrol,2,000toafriendnamedAliceanddistributed5,000ofthemviaacrowdsale.Thismeansthatyounolongercontrolover50%ofthevotesintheDAO,andif

  • Aliceandthecommunitybandstogether,theycanoutvoteanyspendingdecisiononthe100ethersraisedsofar.Thisisexactlyhowademocracyshouldwork.Ifyoudon'twanttobeapartofyourcountryanymoretheonlythingyoucandoissellyourowntokensonadecentralizedexchangeandoptout,butyoucannotpreventtheothersfromdoingso.Soopenyourconsoleandlet'sgetreadytofinallyputyourcountryonline:vardaoSource='contracttoken{functionsendToken(addressreceiver,uint256amount)returns(boolsufficient){}functiongetBalance(addressaccount)returns(uint256balance){}}contractDemocracy{uintconstantminimumQuorum=100uintconstantdebatingPeriod=7daystokenvoterShareuintnumProposals=0addressfoundermapping(uint=>Proposal)proposalsstructProposal{addressrecipientuintamountbytes32descriptionHashuintcreationDateuintnumVotesuintquorumboolactivemapping(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(uintproposalID){if(voterShare.getBalance(msg.sender)>0){proposalID=numProposals++Proposalp=proposals[proposalID]p.recipient=_recipientp.amount=_amountp.descriptionHash=_descriptionHashp.creationDate=nowp.numVotes=0p.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||_positionp.creationDate+debatingPeriod&&p.active){uintyea=0uintnay=0for(uinti=0i0){yea+=voteWeight}if(v.positionminimumQuorum&&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,bypointingittothecorrectaddressofthetokencontractyoucreatedpreviously.Let'salsoregisteranameforyourcontractsoit'seasilyaccessible(don'tforgettocheckyournameavailabilitywithregistrar.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,showingithasnoproposalsyet.Whiletheproposalcountis0,thefounderoftheDAOcanchangetheaddressofthetokentoanythingitwants.Afteryouaresatisfiedwithwhatyouwant,it'stimetogetallthatetheryougotfromthecrowdfundingandintoyournewcountry:eth.sendTransaction({from:eth.accounts[1],to:daoAddress,value:web3.toWei(100,"ether")})Thisshouldtakeonlyaminuteandyourcountryisreadyforbusiness!Now,asafirstpriority,yourcountryneedsaniceflag,butunlessyouareaflagexpert,youhavenoideahowtodothat.Forthesakeofargumentlet'ssayyoufindthatyourfriendBobisagreatflagdesignerwho'swillingtodoitforonly10ethers,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,anyonecanchecktheproposalrecipientandamountbyexecutingthesecommands:

  • daoInstance.getProposalRecipient.call(0)daoInstance.getProposalAmount.call(0)Unlikemostgovernments,yourcountry'sgovernmentiscompletelytransparentandeasilyprogrammable.Asasmalldemonstrationhere'sasnippetofcodethatgoesthroughallthecurrentproposalsandprintswhattheyareandforwhom:functioncheckAllProposals(){

    for(i=0i

  • varproposalID=0varposition=1//+1forvotingyea,1forvotingnay,0abstainsbutcountsasquorumdaoInstance.vote.sendTransaction(proposalID,position,{from:eth.accounts[0]})Unlessyouchangedthebasicparametersinthecode,anyproposalwillhavetobedebatedforatleastaweekuntilitcanbeexecuted.Afterthatanyoneevenanoncitizencandemandthevotestobecountedandtheproposaltobeexecute.Thevotesaretalliedandweightedatthatmomentandiftheproposalisacceptedthentheetherissentimmediatelyandtheproposal.Ifthevotesendinatieortheminimumquorumhasntbeenreached,thevotingiskeptopenuntilthestalemateisresolved.Ifitloses,thenit'sarchivedandcannotbevotedagain.varproposalID=0daoInstance.executeProposal.sendTransaction(proposalID,{from:eth.accounts[0]})IftheproposalpassedthenyoushouldbeabletoseeBob'sethersarrivingonhisaddress:eth.getBalance(registrar.addr("bob"))Tryforyourself:Thisisaverysimpledemocracycontract,whichcouldbevastlyimproved:currently,allproposalshavethesamedebatingtimeandarewonbydirectvoteandsimplemajority.Canyouchangethatsoitwillhavesomesituations,dependingontheamountproposed,thatthedebatemightbelongerorthatitwouldrequirealargermajority?Alsothinkaboutsomewaywherecitizensdidn'tneedtovoteoneveryissueandcouldtemporarilydelegatetheirvotestoaspecialrepresentative.Youmighthavealsonoticedthatweaddedatinydescriptionforeachproposal.Thiscouldbeusedasatitlefortheproposalorcouldbeahashofalargerdocumentdescribingitindetail.

    Let's go exploring! Youhavereachedtheendofthistutorial,butit'sjustthebeginningofagreatadventure.Lookbackandseehowmuchyouaccomplished:youcreatedaliving,talkingrobot,yourowncryptocurrency,raisedfundsthroughatrustlesscrowdfundingandusedittokickstartyourownpersonalcountry.Forthesakeofsimplicity,thesimpledemocraticorganizationyoucreatedcanonlysendetheraround,thenativecurrencyofethereum.Whilethatmightbegoodenoughforsome,thisisonly

  • scratchingthesurfaceofwhatcanbedone.Intheethereumnetworkcontractshaveallthesamerightsasanynormaluser,meaningthatyourorganizationcouldbeprogrammedinsuchwaythatitcoulddoanyofthetransactionsthatyouexecutedcomingfromyourownaccounts.Whatcouldhappennext?

    ThegreetercontractyoucreatedatthebeginningcouldbeimprovedtochargeetherforitsservicesandcouldfunnelthosefundsintotheDAO.

    Thetokensyoustillcontrolcouldbesoldonadecentralizedexchangeortradedforgoodsandservicestofundfurtherdevelopthefirstcontractandgrowtheorganization.

    YourDAOcouldownit'sownnameonthenameregistrar,andthenchangewhereit'sredirectinginordertoupdateitselfifthetokenholdersapproved.

    Theorganizationcouldholdnotonlyethers,butanykindofothercoincreatedonethereum,includingassetswhosevaluearetiedtothebitcoinordollar.

    TheDAOcouldbeprogrammedtoallowaproposalwithmultipletransactions,somescheduledtothefuture.

    ItcouldalsoownsharesofotherDAO's,meaningitcouldvoteonlargerorganizationorbeapartofafederationofDAO's

    TheTokenContractcouldbereprogrammedtoholdetherortoholdothertokensanddistributeittothetokenholders,linkingthereforethevalueofthetokentothevalueofotherassets,sopayingdividendscouldbeaccomplishedbysimplymovingfundstothetokenaddress

    Thisallmeansthatthistinysocietyyoucreatedcouldgrow,getfundingfromthirdparties,payrecurrentsalaries,ownanykindofcryptoassetsandevenusecrowdsalestofunditsactivities.Allwithfulltransparency,completeaccountabilityandcompleteimmunityfromanyhumaninterference.Whilethenetworklivesthecontractswillexecuteexactlythecodetheywerecreatedtoexecute,withoutanyexception,forever.Sowhatwillyourcontractbe?Willitbeacountry,acompany,anonprofitgroup?Whatwillyourcodedo?That'suptoyou.

  • More stuff to do Youaccomplishedalottoday,youshouldfeelproud.Butifyouarestillthirstyforknowledge,herearesomecoolprojectsthatareliveandyoucanparticipatein:

    Etherex Augur eDollar Redditflairmanager(suggestion:basiccontractwhereuserscanrequestfrontierflairsin

    thesubreddit) etc..

    More references https://github.com/ethereum/wiki/wiki/SolidityTutorialhttps://dappsforbeginners.wordpress.com/tutorials/contractsthatsendtransactions/