Friday, May 22, 2015

Building an ethereum ÐApp, pt. II

Hiccups on the way to ÐApping

What is ethereum and ÐApps? Check here  or search
This is part I of a series. Part I

Not using enough gas for transactions

You know it - you send a transaction, scratch your head but nothing happens. You wait, see blocks being crafted but your transaction is just sitting there, forgotten. When you check its status using

// 0xTRANSACTIONID is the return value from eth.sendTransaction
// or you can see it in the verbose logs of geth
eth.getTransaction('0xTRANSACTIONID').blockNumber


you get either 0 or an error. 

Make sure you are using enough gas for the operation. Each transaction in ethereum can be one of the following 3 types
  1. just value transfer (sending eth to your friend)
  2. invoke a contract (possibly with value transfer)
  3. create a contract
And each requires a different amount of gas. Excess gas is refunded so you can beef it up easily. For example to deploy my contract, I would use this call:

eth.sendTransaction({from: eth.accounts[0], data=code, gas=1800000})


Not enabling CORS for HTML5 apps

If you decided to access the geth client from a JS+HTML5 app, you may find that the web3.js module is unable to connect because of the Cross-Origin Resource Sharing restrictions in the browser. You can see it in the F12 Developer Tools console. To fix this, make sure you have launched your geth instance with the correct arguments. If your JS app is served from http://localhost:3000, it would look like this:

geth --rpc --rpcaddr="localhost" --rpcport="8545" --rpccorsdomain="http://meteor-dapp-cosmo.meteor.com http://localhost:3000"

The --rpccorsdomain argument is key, it allows these origins to access the RPC. Note that you can specify more than one domain, just separate with spaces. This commandline will allow you to run the Cosmo web app at http://meteor-dapp-cosmo.meteor.com with your local geth client.

Note that if you try to invoke the HTTP RPC requests manually, you won't get the Access-Control-Allow-Origin: header unless you add the Origin: header first.


Incorrect compilation or construction

When you pack your little contract's lunch and send it off to the cloud, it may fail to stick even though you gave him enough gas to fly all the way to the cloud and the transaction was processed. But when you execute

eth.getCode(0xCONTRACTADDR)

you get '0x' nada nothing. It will be useful to know that the EVM bytecode that you send as data is executed and the result will be the actual contract code living on the blockchain. This is how the constructors work.

If your code is corrupt or the constructor encounters a problem, you may end up in this situation. In my case, I incorrectly copied the hex contract output from the compiler.


Meteor: global variables

I tried to instantiate a contract client in my Meteor app in a template.js file like this:

RegistrarABI = [{"constant":true,"inp.....snip RegistrarAddr = "0xc6d9d2cd449a754c494264e1809c50e34d64562b"; RegistrarAPI = web3.eth.contract(RegistrarABI); Registrar = RegistrarAPI.at(RegistrarAddr);

but alas, these variables were not available in my helpers or elsewhere.

Turns out that Meteor executes template JS code in a different context and so these variables were not global. My quick&dirty solution was to attach them to the window which is global but a better approach is clearly putting that into the client/compatibility folder which is designated for "outsiders".


ADDED: Development FAQ

You can join the go-ethereum gitter channel and search, many questions have been asked there already and there are some examples / clarifications too. Just remember to not be an ass and try to search a bit first before distracting the devs.

2 comments:

  1. We are using Windows 8. We created a web wallet and got this error and the on our web page, The account balance does not show. How can we fix? Thanks for your assistance. geth --rpc --rpccorsdomain "http://earth-dollar.united-earth.vision" --unlock 0

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete