Skip to main content

"Hello World" with counter

Friend of mine pointed out that the "Hello World" contract described in my previous post does not keep state. Reading and writing data to the blockchain is important and can be challenging. In this post I will add a counter to count number of times the sayHello() function was called.   

Step 1. Create  a new contract

Let's create a file HelloWithCounter.sol and put it into the "contracts" directory.
pragma solidity ^0.4.4;

contract HelloWithCounter {
  uint private helloCounter;

  function Hello() public {
    // constructor
    helloCounter = 0;
  }

  function sayHello() public returns (string) {
     helloCounter = helloCounter+1;
     return strConcat('I say Hello #', uintToString(helloCounter));
  }

  function getHelloCounter() constant public returns (string) {
     return uintToString(helloCounter);
  }

  function uintToString(uint v) internal pure returns (string str) {
      uint maxlength = 100;
      bytes memory reversed = new bytes(maxlength);
      uint i = 0;
      while (v != 0) {
        uint remainder = v % 10;
          v = v / 10;
          reversed[i++] = byte(48 + remainder);
      }
      bytes memory s = new bytes(i);
      for (uint j = 0; j < i; j++) {
          s[j] = reversed[i - 1 - j];
      }
      str = string(s);
  }

  function strConcat(string _a, string _b) internal pure returns (string) {
        bytes memory _ba = bytes(_a);
        bytes memory _bb = bytes(_b);
 
        string memory ab = new string(_ba.length + _bb.length);
        bytes memory bab = bytes(ab);
        uint k = 0;
        for (uint i = 0; i < _ba.length; i++) {
          bab[k++] = _ba[i];
        }
        for (i = 0; i < _bb.length; i++) {
          bab[k++] = _bb[i];
        }
        return string(bab);
    }
}


Step 2. Update 2_deploy_contracts.js (in migrations directory) to include new contract. 

Here is how the file should look after the update:
var Hello1 = artifacts.require("./Hello.sol");
var Hello2 = artifacts.require("./HelloWithCounter.sol");


module.exports = function(deployer) {
  deployer.deploy(Hello1);
  deployer.deploy(Hello2);
};



Step 3. Start the console

$ truffle console↵


Step 4. Deploy new contract 

truffle(development)> truffle migrate --reset↵
Using network 'development'.

Running migration: 1_initial_migration.js
  Replacing Migrations...
  ... 0x2dd16d6427594963fce6c0b876bb97eccb686665d28e8a0fb474e8aaef63fd8c
  Migrations: 0xac37a9866815625c4a4c6aa0fc60116e495b1df5
Saving successful migration to network...
  ... 0x5cb753bc95a68ae74a6153b5253686e2286cbe28fa823656f0efcdfa86b010fb
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Replacing Hello...
  ... 0x32884e4eafe5754c0144daa90a74812b53baea3e132f8a160ee99672e91503cc
  Hello: 0x320b839e89a460384ec01919614c7399f80c5213
  Replacing HelloWithCounter...
  ... 0xda8e7f43f62fcd94ffe478b1f135b31640ef8872c97278f10eab7c47b71405f8
  HelloWithCounter: 0xec2a49fb14e9e5b52d4236f9e27e3c45dfeb44b1
Saving successful migration to network...
  ... 0xda21ca9b4bae886293e7f7f3b06a3beaa6b33e67d9f97d88b5a9e5d35ba6ad86
Saving artifacts...

Step 5. Check the contract 

First let's see the counter before any calls to the sayHello()
truffle(development)> var hc = HelloWithCounter.at(HelloWithCounter.address)↵
undefined
truffle(development)> hc.getHelloCounter()↵
''

No surprises here. Counter is empty.


Now let's  say "Hello" for couple times:
truffle(development)> hc.sayHello()
{ tx: '0xd2579761083d00e3d2130cc59bba08ea1e6befa3323f1836c60e99f95da03cfe',
  receipt:
   { transactionHash: '0xd2579761083d00e3d2130cc59bba08ea1e6befa3323f1836c60e99f95da03cfe',
     transactionIndex: 0,
     blockHash: '0x8bb3e28112468c8ed46ea875e157112cc1c79a258062ffeb6756da2706f9c42a',
     blockNumber: 70,
     gasUsed: 47195,
     cumulativeGasUsed: 47195,
     contractAddress: null,
     logs: [],
     status: 1 },
  logs: [] }
truffle(development)> hc.sayHello()
{ tx: '0x57f25d5faf5efaf14d6c77698edb3ed7f6ee2a2cb7f7fa29d87970571ba9e19f',
  receipt:
   { transactionHash: '0x57f25d5faf5efaf14d6c77698edb3ed7f6ee2a2cb7f7fa29d87970571ba9e19f',
     transactionIndex: 0,
     blockHash: '0x16e9d46ca85c902663812cb60e7a0885c0647b2e9196e32b9e698707c24b1f3c',
     blockNumber: 71,
     gasUsed: 32195,
     cumulativeGasUsed: 32195,
     contractAddress: null,
     logs: [],
     status: 1 },
  logs: [] }

Note that some gas is needed to call this function. That's the price for writing data to the Etherium blockhain and (a little bit) for the time of running this function within virtual machines on the network,

Let's check the counter again:
truffle(development)> hc.getHelloCounter()↵
'2'


Comments

Popular posts from this blog

Posting to FaceBook feed using Graph API

Graph API was announced at F8 with a promise to dramatically simplify the FB API. I checked the read access over the new interface during the presentations and to my big surprise it worked flawlessly and from the first time. When I tried https://graph.facebook.com/facebook, JSON-formatted info about the FaceBook page was returned (as expected).
Then I tried OAuth 2.0 way of accessing the API to post a message to the feed. And to my even bigger surprise it worked too!
Here is what you need to do to access Graph API over OAuth: 1. Create a FB app, store app properties to a file:
$appkey='7925873fbfb5347e571744515a9d2804'; $appsecret='THE SECRET'; $canvas='http://apps.facebook.com/graphapi/'; 2. Create a page that will prompt user the access permission (I am prompting for the publish_stream and offline_access permissions at the same time)
//http://apps.facebook.com/graphapi/ require'settings.php';
$url="https://graph.facebook.com/oauth/authorize?"; $url.=…

Amazon Simple Email Service (Amazon SES) and PHP

This morning Amazon announced availability of a bulk email delivery service called "Simple Email Service". Anyone who knows how much pain is it to set-up scalable email solution (and it is not just spammers who need it!) should celebrate the occasion. I know of a company that spent several years cleaning ip addresses it sends email and found itself locked into the contract with internet provider since it would take forever to reach required level of email deliver ability anywhere else.

Anyway, this evening I decided to check the Amazon claim that the service is "simple". Found out that it is indeed simple!
Since there is not much in terms of the documentation yet, here is my code where I used AWS PHP library:

// Enable full-blown error reporting. http://twitter.com/rasmus/status/7448448829
error_reporting(-1);

// Set plain text headers
header("Content-type: text/plain; charset=utf-8");

// Include the SDK
require_once '../sdk.class.php';


// Instantiate th…

Respect Coin

Respect I think it's time to talk about currency. Let's create a Respect Coin.
Step 1. Install OpenZeppelin library npm install zeppelin-solidity
When it comes to coins, I like to use some functions that smart people already implemented and other smart people verified. I think that Zeppelin is a nice collection of Solidity contracts that can be trusted. Let's use the StandardToken contract and use it as a parent class for our own RespectCoin contract.
Step 2. Create RespectCoin contract and store it in "contracts/RespectCoin.sol" file pragma solidity ^0.4.4; import "../node_modules/zeppelin-solidity/contracts/token/StandardToken.sol"; /** * @title RespectCoin * @dev ERC20 Token example, where all tokens are pre-assigned to th e creator. * Note they can later distribute these tokens as they wish using `transfer` and other * `StandardToken` functions. */ contract RespectCoin is StandardToken { string public constant name = "RespectCoin&quo…