Monthly Archives: June 2016

Converting strings to integers in Solidity

If I have a string representation of a number in the Solidity programming language, how do I convert it to one of the integer types? There are casting operations for converting between the different numeric types:

int8 y = -3;
uint x = uint(y);

But there doesn’t seem to be a built-in string to integer converter. After much Googling and asking the folks at Oraclize for help on on another issue, we found a solution – there is a “parseInt” function built into the Oraclize library. The source code of the relevant function is reproduced here because the nice folks at Oraclize have allowed their code to be used freely:

This code looks through each byte of the string in turn, ensuring it is an ASCII digit and raising it to the appropriate power of ten to convert a string of digits into an integer.

If you are already using Oraclize in your Ethereum contract, then you should have “parseInt” built-in, otherwise you are free to use this code (with the copyright notice) in your own code.

Ethereum – Gas for Dummies

I’ve been trying to figure out what Gas means in Ethereum. There is lots of information out there but I will add to it by describing what I found in my own words.

Gas is just a unit of currency, like a token. It is used to set a price on different types of code execution inside the Ethereum Virtual Machine (EVM). For example, saving a variable cost 100 gas; executing an IF statement cost 1 gas. There is a list of how much gas things cost here.

In a typical transaction you would say something like

method.sendTransaction({from:eth.accounts[0], gas:300000})

The gas part of that statement means that you are willing to spend up to 300,000 of these gas tokens in executing this method.
Now, there is another, optional, parameter in that statement, which is gasprice. This is the price in Wei that you are willing to pay for each gas token. If gasprice is not specified, then a default value is used. At the moment that value is 10 szabo, or 0.00001 Ether.

What is the point of all this?

Contracts on the Ethereum blockchain are of varying sizes and complexity. Therefore, a miner who is investing their computing power executing a method (a part of a contract) needs to be rewarded according to how much of that power they need to use. By inserting an amount of gas and a gasprice, you are signalling to the miner how much reward they can reap from running your code.

This is fundamentally different to the Bitcoin blockchain, where the vast majority of code executions are identical (transferring bitcoin from one wallet to another) and therefore miners can predict how much it will cost them to execute every transaction in a block.

So, going back to our example, when you send in the above transaction, the paying account (eth.accounts[0]) is deducted 300,000 * 0.00001 ETH, i.e. 3 ETH, and that value is sent in with the method call.

After that, one of two things will happen:

  1. The execution requires as many or fewer of the gas tokens that you pledged. In that case the execution is succesful and you are refunded however much ether is unspent (e.g. if you said you were willing to use up 300,000 gas tokens at 0.00001 ETH each, but the execution only required 150,000 gas tokens, then you get refunded 150,000 * 0.00001 ETH. The miner keeps the rest as a reward for their efforts.
  2. The execution requires more gas tokens that you are willing to spend. In that case, execution of the code is aborted when the gas limit is reached and the contract state goes back to whatever it was before your execution started, i.e. nothing actually gets done. BUT crucially you DON’T get your money back (because work was done by the miner, so they used up their computing power and electricity).

Some thoughts

  • The higher the gasprice you insert the more attractive it is for miners to process your transaction because they get paid gasprice for every gas token that they need to use in executing your transaction.
  • It seems almost impossible to be able to calculate how much gas a transaction will require. A dummy like me has to send a big number of gas to ensure execution. There are obviously ways of calculating this, because if you use the Mist browser to execute a method, it seems to have a way of forecasting the amount of gas you might need.
  • It is also very difficult to find out that your transaction failed because of lack of gas. It just dies and you are left to puzzle it.
  • Interestingly, blocks also have a gas limit. But that is probably for another post!

    Useful links

    I found these links useful when reading up on gas. Enjoy!

An Ethereum Project (4) – The Lottery Orchestrator

In my previous post I described a instance of a single lottery draw. But how does a punter who wants to buy a ticket know where to buy it?

In the world of Ethereum that is not so easy. You can install geth on your computer and then create a wallet and put some ETH into it. After that, you would construct a draw object with the address and abi definition of the draw and then call draw.buyTicket with the right amount of gas to make sure your transaction goes through.
This is a process that excludes 99.99% of the population of the world!

There is a slighlty easier way, which is to use the Ethereum Mist wallet, which does most of the above for you. All you have to do is create your wallet and put ETH into it. You can then “follow” a contract (e.g. a draw) and call its methods (e.g. buyTicket).

But every instance of a draw will be at a different address on the blockchain, so how do you find the current one?

Enter Lottereo, our Lottery Orchestrator! Lottereo is basically a register of draws. It knows where the latest draw is and lets you buy tickets in the it. It will also give you information about the winners of previous draws. And all you have to do is follow the Lottereo contract in your Mist browser.

Let’s take it one step at a time. The contract defines a few variables to begin with, to hold draw information:

contract lottereo {
   address owner;
   uint public numDraws;
   struct drawData {
      uint drawDate;
      address eth_address;
   }
   mapping(uint => drawData) public draws;
    .
    .
    .
}

Its constructor defines the owner and initialises the number of draws to 0:

 function lottereo()  {
      numDraws = 0;
      owner = msg.sender;
   }

And we can define some simple functions to add a new draw, get the latest and the previous draws:

 function addDraw (address _eth_address) {
      if (msg.sender != owner) throw;
      draws[numDraws] = drawData(now, _eth_address);
      numDraws += 1;      
   }

   function getLatestDraw () constant returns (address _latest) {
      if (numDraws == 0) throw;
      _latest = draws[numDraws-1].eth_address;
   }

   function getPreviousDraw () constant returns (address _previous) {
      if (numDraws < 2) throw;
      _previous = draws[numDraws-2].eth_address;
   }

The Orchestration Bit

Crucially, within it is another contract call we call "drawInterface". This is basically a class with some "shell" methods in it which are a carbon copy of those in the draw contract:

contract drawInterface {

  uint public winningNumber;  

  function getPot() constant returns (uint) {
  }
 
  function buyTicket (address _buyer, uint _guess) {
  }
  
  function getPrizeValue (address _query) constant returns(uint) {
  }

}

This allows us to define variables of this class that live at a specified address (i.e. a draw instance on the blockchain) and then call the methods that exist inside that specific instance (because they have the same name in the draw contract and in the Lottereo class definition). So, for example, this is how you buy a ticket through Lottereo for the current draw:

 function buyTicket(uint _guess)  {
     drawInterface draw = drawInterface(getLatestDraw());
     draw.buyTicket.value(msg.value)(msg.sender,_guess);
   }

And this is how you know what the winning number is of the last draw that was drawn:

 function getWinningNumber ()  constant returns (uint _winner){
      drawInterface draw = drawInterface(getPreviousDraw());
      _winner = draw.winningNumber();
   }

So now, a user only has to be able to install the Mist Browser and know the address and ABI definition of the Lottereo contract to play in whichever draw is the current draw. So maybe now we are only excluding 99% of the population instead of 99.99% :-)

The Lottereo contract is here. Again, this is work in progress so things may change from what is described above.

Want to try it?

The Mist browser allows you to point to the real Ethereum blockchain or to the test blockchain, called Morden. If you point to Morden and create a wallet there, you can then get some fake ETH from here.

Our current Lottereo contract is at this address:

0x93ff7ee96a55f777f311f511b19586393f5598df

And its abi definition is:

[{
    constant: true,
    inputs: [{
        name: "",
        type: "uint256"
    }],
    name: "draws",
    outputs: [{
        name: "drawDate",
        type: "uint256"
    }, {
        name: "eth_address",
        type: "address"
    }],
    type: "function"
}, {
    constant: true,
    inputs: [],
    name: "getPot",
    outputs: [{
        name: "pot",
        type: "uint256"
    }],
    type: "function"
}, {
    constant: true,
    inputs: [],
    name: "getLatestDraw",
    outputs: [{
        name: "_latest",
        type: "address"
    }],
    type: "function"
}, {
    constant: false,
    inputs: [{
        name: "_guess",
        type: "uint256"
    }],
    name: "buyTicket",
    outputs: [],
    type: "function"
}, {
    constant: false,
    inputs: [{
        name: "_eth_address",
        type: "address"
    }],
    name: "addDraw",
    outputs: [],
    type: "function"
}, {
    constant: true,
    inputs: [],
    name: "getWinningNumber",
    outputs: [{
        name: "_winner",
        type: "uint256"
    }],
    type: "function"
}, {
    constant: true,
    inputs: [],
    name: "numDraws",
    outputs: [{
        name: "",
        type: "uint256"
    }],
    type: "function"
}, {
    constant: true,
    inputs: [],
    name: "getPreviousDraw",
    outputs: [{
        name: "_previous",
        type: "address"
    }],
    type: "function"
}, {
    constant: true,
    inputs: [{
        name: "_query",
        type: "address"
    }],
    name: "getPrizeValue",
    outputs: [{
        name: "_value",
        type: "uint256"
    }],
    type: "function"
}, {
    inputs: [],
    type: "constructor"
}]

So have a go and tell us what you think!

An Ethereum Project (3) – A draw

The Lottery Draw

Imagine a lottery where each “ticket” costs a certain amount of ether. When buying a ticket you are allowed to guess one number between 1 and 1,000. Your ticket “id” is simply the wallet address you use to pay the ether with, and it is associated with your guess. You can buy as many “tickets” as you like. Every time you pay and guess, your wallet address is entered again.
At the appointed time, the draw is made (a number is selected randomly) and the pot is divided equally between and paid to any addresses that correctly guess the number (minus a percentage commission for the organiser of the draw). If no one guesses correctly, then the pot (minus the commission to the organiser) gets transferred to the next lottery draw (a rollover) and the process starts again.

The “draw” contract

Each instance of the lottery we will call a “draw”. Our draw contract first declares a bunch of variables (see here for Solidity data types):

contract draw {
    address owner;
    uint public numTickets;
    uint public drawDate;
    uint public actualDrawDate;
    bool public drawn;
    uint public entryFee;
    uint public payout;
    uint public winningNumber;  
    address public organiser;
    address public nextDraw;  
    address public previousDrawAddress;
    struct Ticket {
     uint guess;
     address eth_address;
    }
    mapping(uint => Ticket) public tickets;
    address[] public winningaddresses;
     .
     .
     .
}

If you declare them as “public” then you can access them later by calling, for example, draw.numTickets() from the geth console.

The Constructor

After that, you have a constructor function, which gets called once when the contract is “mined”:

     function draw(uint _offset, uint _entryFee, address _organiser, address _previousDrawAddress) {
         owner = msg.sender;
  	 numTickets = 0;
   	 drawn = false;
   	 winningNumber = 0;
         payout = 0;
         drawDate = now + _offset;
         actualDrawDate = 0;
         entryFee = _entryFee;
         organiser= _organiser;
         previousDrawAddress = _previousDrawAddress;
    }

In our contract constructor we initialise all the variables, including setting the owner (who is the only one who can perform certain crucial functions later), the entry fee (i.e. the cost of each ticket), the address of the organiser (who will collect the commission fee) and the address of the previous draw (more on this later, but this is basically so that draws can be daisy-chained together). We also set the drawDate, which is the earliest possible date that the draw can be made.

Buying a ticket

The buyTicket function allows anyone who knows about this contract to buy a ticket:

    function buyTicket(address _buyer, uint _guess) returns (uint ticketid) {
      if (msg.value != entryFee) throw;
      if (_guess > 1000 || _guess < 1) throw;
      if (drawn) throw;
      ticketid = numTickets++;
      tickets[ticketid] = Ticket(_guess, _buyer);
      BuyTicket(ticketid);
    }

If the value sent in by the ticket buyer is not the exact entry fee, then they will not be allowed to buy a ticket. Also, a ticket cannot be bought if the draw has already taken place!
If all conditions are met, the buyer's address and guess are entered in the draw by adding them to our tickets array.
The last line,

      BuyTicket(ticketid);

is an Event trigger (Events are outlined here.). I won't go into detail on that because it is incidental to the rest.

Doing the draw

On or after the appointed time (drawDate) the draw can be made by calling this function:

    function doDraw() {
     if (drawn) throw;
     if (now < drawDate) throw; 
     winningNumber = (now % 1000) +1 ;
     actualDrawDate = now;
      for (uint i = 0; i < numTickets; ++i) {
        if (tickets[i].guess == winningNumber) {
          winningaddresses.push(tickets[i].eth_address); 
        }
      }
      var commission = numTickets*entryFee / 10;
      payout = this.balance - commission;
      for (uint j = 0; j < winningaddresses.length; ++j) {
        winningaddresses[j].send(payout / winningaddresses.length);
      }
      organiser.send(commission);
      DrawDone(winningNumber);
      drawn = true;
    }

The main thing to note here is that our "random" selection of a number between 1 and 1,000 is very crude. It is a massive problem with Solidity at the moment that it does not have a Rand() function. Almost anything about a blockchain is deterministic by design, so it is incredibly hard to generate randomness from things available from within the contract. We are going to be doing more work on this later, possibly integration this randomness contract. We will report back on that later. For now, let's assume that we have good randomness to generate a number between 1 and 1,000.

Crucially, any one could trigger the draw, not just the contract owner. So once a draw contract is out there on the blockchain and the earliest draw date has passed, even if he owners disappear the draw can still be held.

Once the winningNumber is obtained, we cycle through all the tickets to figure out if we have any winners, which are pushed into an array of wnningaddresses.

Paying out

The lottery pot is contained in the contract balance (this.balance).
A commission is calculated (10% of tickets bought), paid to the organiser. The remaining amount is assigned to a payout variable, divided between the winners and paid out to their wallets.

Note that if there are no winners, no more funds will be drained from the contract balance, which leads to....

The rollover

In the event that there are no winners, the pot gets rolled over into the next draw with this function:


    function transferPot(address _newContract) {
      if (msg.sender != owner) throw;
      if (this.balance == 0) throw;
      if (!drawn) throw; 
      _newContract.send(this.balance);
      nextDraw = _newContract; 
    }

This can only be done by the contract owner. It requires that a new draw contract be created that can receive the funds (_newContract). So basically the draws need to be daisy-chained so that one draw can send funds to the next one.

Other helpful functions

Additionally, we have a few functions that allow someone to query the contract to see if they have won:

    function getPrizeValue (address _query) constant returns (uint _value) {
      if (!drawn) throw;
      _value =0;
      for (uint i = 0; i < winningaddresses.length; ++i) {
        if (winningaddresses[i] == _query) {
          _value += payout / winningaddresses.length;        
        }
      }
    }

...and another one to obtain the size of the current pot:


    function getPot() constant returns (uint) {
       return this.balance; 
    }

The whole contract is here. It is still a work in progress, particularly in light of the recent problems with the DAO and the advice regarding how one should use the .send function to try to avoid getting scammed.

So now we have a draw and anyone can buy a ticket. But how the hell do they find it and actually buy a ticket? Read on....

An Ethereum Project (2) – The testing setup

The hardware

We have the whole thing running on an old laptop with an Intel T5550 and 2GB of RAM, on which we installed Ubuntu server

The software

There are various ways to access Ethereum and various languages to code in. We used geth as the command line interface, and chose Solidity as our programming language (you’ll need the solidity compiler as well).

Initially, we followed the instructions here to create a private testnet. You can set that off to mine for ether (miner.start(1) from the command line) and create untold riches while you mine your test contracts!

If you don’t know how to write, compile and deploy a basic contract to the Ethereum blockchain, I recommend you give the Greeter contract a go before you continue here, as it has simple step-by-step instructions that can then be applied elsewhere.

Once you know how to deploy a basic contract, you can have a look at our lottery one.

An Ethereum Project (1) – The idea

A decentralised lottery

A lottery draw is an event where three things need to happen:

    1. Players need to buy tickets and trust that these are entered in the draw. A pot is made with the ticket money in a transparent way – e.gg 10% goes in admin fees and the rest in prizes.

    2. A draw needs to take place where numbers are selected at random. Everyone needs to trust that the draw is truly random.

    3. The winner(s) need to be paid a portion of the pot. Everyone needs to trust that winners will be paid fairly. If no winner emerges the pot gets rolled over into the next draw

.

Now, up until now the trust factors have been held by a third party, e.g. the National Lottery. Everyone trusts them to sell the tickets, draw numbers transparently and pay the winners. Most of the flim-flam around those events -tv draws with music and celebrities, big photo ops with cardboard cheques and champagne etc- are just flashy props to hide a pretty straightforward process.

But with Ethereum you could replace all the third party trust. Here’s how:

1. Buy tickets. A draw is a contract on the Ethereum blockchain. You can pay for a ticket with Ether into the contract’s wallet from your wallet. Your wallet address is now your ticket. It is associated to the numbers you chose. Both of those values are stored in the contract. If you win, you get paid into that wallet.
2. Do the draw The pot is the value of ether in the contract. At an appointed draw time the draw is done by the contract picking some numbers at random. It then runs over the database of entries and works out whether or not anyone won.
3. Pay the winner(s). If the smart contract finds a winner or winners, it divides the pot among them and pays out the ether to the winning addresses.
4. Rollovers – if there is no winner it can transfer the pot to the smart contract of the next draw.

The beauty of this?

1. It is anonymous (or pseudonymous). You play with your ether wallet address. You get paid to your ether wallet address. No need to register. You can buy as many tickets as you want. Every time you pay, your address is entered again.
2. It is totally transparent and auditable. For every draw, you publish the address that receives the money, so anyone can go and figure out if the pot is correct. You can also see who paid into that pot (i.e. who was entered into the draw) and even what numbers they chose.
The smart contract is also public, i.e. the algorithm that picks the numbers, and the address(es) of the winner(s) are known. And it can be demonstrated that the winners got paid (because the draw contract publicly pays out). All of which means that…
3. It is trust-less. No third party is required to ensure things are above board. Anyone can check.

Easy, right? So my friend Glynn and I decided to have a crack at it. Read on…