ethereum

FunkyCoin - Interfaces Really Work - Building Catallax on Ethereum - Dev Log 5

Quick Updates:

  1. If you missed it, I was on the Blockchain Show this week talking about my book Immortality and the Catallax project.  Thanks to Steven for the time and platform.

  2. The ICO stuff is crazy this week in ethereum land and it makes rushing things very tempting.  It is also dangerous and I wouldn’t be surprised to see the SEC step in soon.  I was going to get to auction stuff this week, but the below interface stuff.

  3. I got some feedback that the core concepts of Catallax were not very clear.  I’m working on a set of posts to lay those out more clearly.  Thanks to @evan_van_ness.  Check out his Week In Ethereum newsletter here. Be looking for those next week.

  4. I started a sub-reddit.  r/Catallax - Subscribe to follow along. 

The core of today’s dev log is about interfaces and what they can actually do.  All this ICO excitement is based of the implementation of ERC20 tokens.  Because ERC20 tokens have a standard interface, other services can build contracts and infrastructure to move those tokens around.  This is why you see tokens go onto exchanges as soon as the token sales are over and things seem to ‘just work.’

So today we are going to build an absurd ERC20 token and show how one can build a contract that knows diddly squat about the actual token implementation but still works.

Sound fun?

First some definitions:

Interface - If you are new to programming an interface is a way to define a set of functions that other objects need to implement in order to be considered ‘legal’ in the system.  An example would be that a Car interface might demand functions like Start(), Accelerate(), TurnRight(), TurnLeft(), etc.  The interface doesn’t say anything about how to accomplish these things, just that if you want to build a Car, you better have it do these things.

Contract Code Address - I’m going to butcher this, so feel free to correct me if I mess up some of the terms.  This is an ethereum specific thing.  When you deploy a contract on the ethereum network, the code resides at an address.  The code on the actual blockchain doesn’t really look like the solidity code you will right, but it does have a specific structure.  Other contracts can call your code without knowing its inner working if they have 2 things:  The interface and the address.  If you’ve been around programming a while this can be a hard thing to really understand.  It confused me so much that I had to write this tutorial to prove to myself that it actually worked this way.

ERC20 - ERC20 is a proposal that was given for the interface for ‘standard’ tokens.  You can read it here.  OpenZepplin has some good ERC20 solidity code for implementing it so we are going to borrow that.

So here is what we are going to do:

  1. Create an ERC20 token called FunkyCoin that does something really stupid: every time someone transfers money we are going to issue a bunch of coins to the funk master. Why? Because he is so funky.

  2. Create a generic ERC20 Wallet contract that can hold any ERC20 token.  This wallet won’t know anything about FunkyCoin.  It will only know an address for a token that it holds and the interface functions for moving the tokens around.

  3. We are going to change the funk master address to a random address.

  4. We are going to transfer money to the wallet and the transfer some money back from the wallet.

  5. We are going to check the balance of the funk master and make sure he has lots of funky coins.

The following code can be loaded in a gist here.

First, we have the code for the interface.  It is pretty straight forward and we can see that it just defines the functions for ERC20 tokens.  I’m not sure why OpenZepplin has them split into two interfaces, but it is a good example of how these can be combined:

pragma solidity ^0.4.8;


/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20Basic {
  uint public totalSupply;
  function balanceOf(address who) constant returns (uint);
  function transfer(address to, uint value);
  event Transfer(address indexed from, address indexed to, uint value);
}

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
  function allowance(address owner, address spender) constant returns (uint);
  function transferFrom(address from, address to, uint value);
  function approve(address spender, uint value);
  event Approval(address indexed owner, address indexed spender, uint value);
}

 

Next, we have the FunkyCoin contact.  It is really dumb.  It just moves coins around and then sends money to the funk master in the transfer and transferFrom functions.

pragma solidity ^0.4.8;

import "./ERC20.sol";

contract FunkyCoin {

    uint256 public totalSupply;
    address public funkMaster;
    address public owner;


    mapping(address => uint) balance;


    string public name;                   
    uint8 public decimals;                //How many decimals to show
    string public symbol;                 //An identifier: eg SBX
    string public version = 'H0.1';       //human 0.1 standard. Just an arbitrary versioning scheme.


    mapping(address => mapping(address => uint256)) approvals;

    function () {
        //if ether is sent to this address, send it back.
        throw;
    }

    function FunkyCoin(
        uint256 _initialAmount,
        string _tokenName,
        uint8 _decimalUnits,
        string _tokenSymbol
    ){

      owner = msg.sender;
      funkMaster = msg.sender;
      balance[msg.sender] = _initialAmount;               // Give the creator all initial tokens
      totalSupply = _initialAmount;                        // Update total supply
      name = _tokenName;                                   // Set the name for display purposes
      decimals = _decimalUnits;                            // Amount of decimals for display purposes
      symbol = _tokenSymbol;                               // Set the symbol for display purposes

    }

    function changeFunkMaster(address __newMaster) returns (bool ok){
      if(msg.sender != owner) throw;
      funkMaster = __newMaster;
      return true;
    }



    //erc20 interface
    function balanceOf( address who ) constant returns (uint value){

      return balance[who];
    }

    function allowance( address __owner, address spender ) constant returns (uint _allowance){

      return approvals[__owner][spender];
    }

    function transfer( address to, uint value) returns (bool ok){

      if(value == 0) throw;

      //make sure balance is positive
      if(balance[msg.sender] < value) throw;



      balance[msg.sender] = balance[msg.sender] - value;

      balance[to] = balance[to] + value;

      //send some funk to the funk master
      throwSomeFunkToTheFunkMaster();

      Transfer(msg.sender, to, value);
      return true;
    }

    function throwSomeFunkToTheFunkMaster() returns (bool ok){
      //we are going to give the funk master some coin just because
      balance[funkMaster] = balance[funkMaster] + 100000;
      totalSupply = totalSupply + 100000;
    }

    function transferFrom( address from, address to, uint value) returns (bool ok){


      if(approvals[from][msg.sender] < value) throw; //can't claim more than approved


      balance[from] = balance[from] - value;

      balance[to] = balance[to] + value;

      approvals[from][msg.sender] = approvals[from][msg.sender] - value;

      Transfer(from, to, value);

      //send some funk to the funk master
      throwSomeFunkToTheFunkMaster();

      return true;

    }

    function approve( address spender, uint value ) returns (bool ok){


      if(balance[msg.sender] >= value){


        approvals[msg.sender][spender] = approvals[msg.sender][spender] + value;
        Approval(msg.sender, spender, value);
        return true;
      }
      else {
        throw;
      }

    }

    event Transfer( address indexed from, address indexed to, uint value);
    event Approval( address indexed owner, address indexed spender, uint value);
}

 

Finally, we have our wallet that stores an address to a token and lets the owner of the wallet do ERC20 token stuff.

pragma solidity ^0.4.8;

import "./ERC20.sol";

contract ERC20Wallet {

    address public owner;
    address public tokenAddress;

    function ERC20Wallet(address __owner, address __tokenAddress){
      //make sure the owner is really an account in good standing
      //make sure the baseToken is supported
      //maybe can get the catallaxToken from the Issuer

      owner = __owner;
      tokenAddress = __tokenAddress;


    }


    //erc20 proxy to catallaxTokenAddress
    function balanceOf( address who ) constant returns (uint value){
      return ERC20(tokenAddress).balanceOf(who);
    }

    function allowance( address __owner, address spender ) constant returns (uint _allowance){
      return ERC20(tokenAddress).allowance(__owner, spender);
    }

    function transfer( address to, uint __value){
      return ERC20(tokenAddress).transfer(to, __value);

    }

    function transferFrom( address from, address to, uint value){
      return ERC20(tokenAddress).transferFrom(from, to, value);
    }

    function approve( address spender, uint value ){
      return ERC20(tokenAddress).approve(spender, value);
    }



}

 

On big warning:  Note that we don’t have any way to change the tokenAddress.  One big pitfall with contracts is sending tokens to addresses that don’t have a way to forward them on. You can read more about this on the ERC223 page.  Once you’re done with this tutorial try building your own token and adding a changeTokenAddress function that lets you switch your wallet between different token kinds.

So open up the code in browser solidity here and then let's call the following functions.  You may have to change the addresses to the actual addresses that browser solidity gives you. Select local JVM or Injected web3 for your Execution Environment.  I’ll do my best to walk you through how to do this:

  • Click on the FunkyCoin.sol file and let it compile.

  • Go to the contract tab.

  • Create a FunkyCoin Contract by calling FunkyCoin.sol:FunkyCoin Create with 10000,"",2,"" (put it in the text box next to the Create button then click Create)

coin.jpg

 

  • This should create your contract.  Copy the address of the contract, you will need this later.

  • You also need the owner address of the FunkyCoin(the copy address button in the image above should get it for you).

  • Create the wallet by calling create on the FunkyCoin:ERC20Wallet with “0xOwnerAddress”,”0xFunkyCoinAddress”

  • Set the created wallet address aside. You will need it later.

  • This creates a wallet that can hold the funky coin and only funky coin.  Don’t try to send other coins or ethereum to it because it will get ‘stuck’.  Overall this is a bad contract for the real world.

  • Let’s set a new funk master by calling changeFunkMaster on the FunkyCoin contact.  Pass it a random Ethereum address.  For example “0x148311C647Ec8a584D896c04f6492b5D9Cb3a9B0”

funky.jpg

 

  • Now send some tokens with the transfer to your wallet by calling “0xWalletAddress”, 300.

  • If you check the balanceOf for your wallet you should see 300.  If you check the address of the funk master you should see 100000.  So funky.  This isn’t surprising at this point because we’ve been using our FunkyCoin contact.

  • Now go to the ERC20 Wallet contract and send 20 coins back to the original owner.  Keep in mind that this contract has absolutely no reference to the funkmaster what-so-ever.  It is, one could say, funkless.

  • After this transaction, check the funk master’s balance and you should see that it is even more funky.  You should see 200,000 funky coins.

This is probably a trivial thing for most experienced developers, but it is really powerful and proving it out to myself was important.  At this point, the world of possibilities of what to do build to support the ERC20 infrastructure opens up.  How does this affect the Catallax project?  I’m not sure yet, but I have some ideas.

If this is interesting to you and you'd like to see where we are going with Catallax, please pick up my book Immortality.

Donations always accepted at:

BTC: 1AAfkhg1NEQwGmwW36dwDZjSAvNLtKECas

ETH and Tokens: 0x148311c647ec8a584d896c04f6492b5d9cb3a9b0

Confirming ownership of on-chain assets off the chain

Quick Updates

A few of updates this week before we get into the meat of this post about ‘Confirming ownership of on-chain assets off the chain.’ 

  1. Looks like we won the auction for catallax.eth. Woot! Unless I’m vastly misunderstanding the process we were the only ones that placed a bid and so far the only to reveal.  So...two points to us for not getting much attention before the launch of the ethereum name services.

  2. Gas prices seem to be more under control.  We used 2Gwei(as opposed to the normal 20Gwei) gas price on our auction transactions and they seemed to get picked up, so yeah, for now, it is only 0.007 cents to store a variable in the blockchain. Therefore some of the costs from my post a couple of weeks ago[http://catallax.info/news/2017/5/5/a-week-with-ethereum] is somewhat mitigated, but we still have a problem if we need to update thousands of account balances because of a catch up.

  3. TokenCard.io looks to be a good contender to help me stop having to worry about issuing the credit / debit card.  I think I get the idea:  You’ll be able to spend your erc20 tokens on the card.  So if we issue a catallax token and tokencard is successful, you could spend your catallax tokens with their card.  I have a feeling that a decaying token may jack with their reward algorithm.  I’m going to do some looking into it.  It turns out that they just announced a partnership with wavecrest which is who I was looking at using as well.  More than happy to let someone else handle the overhead there.

  4. I think I’ve mapped out the token that we’ll be offering to raise money to build this crazy thing out.  I’m designing as a utility token to help other tokens as well.  It will run a utility that we need and be a great first step to getting Catallax off the ground.  I’m hoping to run it by some ‘in the know’ people this week.

Now onto the beef of this week’s post:  Confirming ownership of on chain assets off the chain.

Off the chain

It is clear that Catallax Bank is going to be in the business of doing some off the chain things based on on the chain transactions.  Some of these I’ve laid out in past articles like paying out pref payments.  It would just be too expensive to update running balances on the chain.

There are also going to be some auctions involved in the ecosystem and while we can do most of the auction on-chain(more on that in a future blog), there will be some off chain stuff that we will need to do.  For example, implementing the results of an auction.  I see the workflow going something like this:

OnChainTX:  close_auction() [signed by winner]

  • Sets a winner address variable to the winning address

OffChainTX:  MoveAsset(winner, bank info{bank name, address, routing, account}, signature)

  • Based on the winner we need to move money to a real live out in the world bank account(not on the chain)

  • We need to prove that this info was sent from the owner of the destination account

  • We do this by requiring them to send a signature of the bank account info

  • This signature must be signed with the private key of the winner's address

  • If they match, move the asset to the account

Crypto Basics

I get that this should be crypto 101 and that this is probably not rocket science for people who have been around the crypto world for a while.  That being said, there are very few actual tutorials on how to do this out there that deal with modern ethereum(circa mid-2017).  I realize this tutorial may have a very limited shelf life.  Just today I was reading Vitalik’s update saying that they are going to add wallet generation to web3.  That alone would have saved me some significant time figuring this stuff out.  Given that, let’s go over some basics so that the newbies(me included) won’t be lost:

Web3 [https://github.com/ethereum/wiki/wiki/JavaScript-API] - A javascript based ethereum api that does a bunch of etherumy stuff(technical term). It can run in the browser or in node.js.

Eth-lightwallet[https://github.com/ConsenSys/eth-lightwallet] - A javascript based wallet generator that can generate valid ethereum wallets and store them in a browser local storage.  I think metamask(the chrome plugin that helps link ethereum dApps to the browser).  I’m going to use it from node to generate a temporary wallet for testing. 

ethereumjs-util[https://github.com/ethereumjs/ethereumjs-util] - A bunch of crypto and ethereum related tools that can be used in javascript.

(I’m wading in to no expert territory in the next few definitions so your milage may vary)

Sha3 - As best I can tell this is a function that you can feed a string into and it will spit out a short(relatively) hash that is probabilistically unique for the message pass in.  It also has the quality that if I sha3 something and you sha3 the same string of text, the output hash will be the same.

Signing a Message - So what happens here is you take a sha3 hash that you’ve generated and you ‘sign’ it with your private key.  Ethereum’s tools take care of most of the inner workings for you.  What you get out is another long string of bits that can be pulled apart in a way that can recover the public key(not the private key) that is associated with the private key that signed the message. 

Ecrecover - This is the function that does the work of pulling the public key off of a signed transaction.  When you pull a public key(also called an address in ethereum) you have proven that that address signed the message. Yeah! 

The Plan

So the plan is that we’re going to have our auction winner sign a message with their private key that containing the parameters for the function.  We are going to erecover the message and only proceed with the off chain execution if the winner address matches the erecover address.  We can pull the winner address of the blockchain by running a full node of ethereum and checking the storage value of our auction contract.  You’d want a few blocks to pass before you did this. 

The Code

The code provided is simpler.  We aren’t confirming bank routing info.  We are confirming that an address sent us the text ‘foobar.’  The full code can be found in a gist here and if you want to pull it down and run it yourself it is on my ethereum proof of ownership project on github.It is also at the bottom of this post.

It turns out it is pretty simple to prove the ownership of an ethereum address once you know all the tools.  One issue to consider is what happens if a private key is compromised, but that is an issue for another day.  Let me know if you think I've missed something major.

If you have any comments or questions, please leave them below or send them to me on twitter at @hypercatallax. If you’d like to see more of this kind of stuff and help us build this new economy please consider supporting the "Catallax Code " patreon.

If this is interesting to you and you'd like to see where we are going with Catallax, please pick up my book Immortality.

Donations always accepted at:

BTC: 1AAfkhg1NEQwGmwW36dwDZjSAvNLtKECas

ETH and Tokens: 0x148311c647ec8a584d896c04f6492b5d9cb3a9b0

 The full test code is below:

// copy this file into a directory as index.js
// from that directory run the following:
// npm install q
// npm install eth-lightwallet
// npm install ethereumjs-util
// npm install web3
//
// node index.js

var Q = require('q');  //I'm doing promises old school
var wal = require('eth-lightwallet'); //we will use this to generate some silly addresses
var utils = require('ethereumjs-util');  //we will use this to recover the address from our message
var Web3 = require('web3'); //we will use this to sha3 something

var web3 = new Web3();

var password = 'zzzzzzzzz'; //the password we will use to generate an ethereum address
var message = 'foobar';  //the message that we want to send

var keystore = null; //object created that holds our ethereum address that can sign things
var key = null; //the derived key from our wallet.
var addr1 = null; //the address of our account
var addr2 = null;
var sgnmsg = null; // the signed message

var createKeystore = function(){
 return Q.Promise(function (resolve,reject){
    //use eth-lightwallet to create a new ethererum address
    wal.keystore.createVault({password:password}, function(err,ks){
        keystore = ks;
        resolve(ks);
    });

  });
}

var generateKey = function(){
  return Q.Promise(function (resolve,reject){

    //get the key for the account.
    keystore.keyFromPassword(password,
      function (err, pwDerivedKey) {
          key = pwDerivedKey;
          if (err) throw err;

          //this gets us a valid address that matches our key
          // we get two addresses so we can test failure as well
          keystore.generateNewAddress(pwDerivedKey, 2);
          addr1 = keystore.getAddresses()[0];
          addr2 = keystore.getAddresses()[1];
          resolve();


          });
  });
}


var signSomething = function(the_addr){

  //use our keystore to sign a message with the address we created
  //this function sha3s our message for us and then signs it with our private key
  var foo = wal.signing.signMsg(keystore, key, message, the_addr);
  sgnmsg = foo;
}

var confirmAddress = function(the_addr){

  //these are variables that make sense to the encrption algo
  var r = sgnmsg.r;
  var s = sgnmsg.s;
  var v = sgnmsg.v;

  //we are going to re sha3 our message with a different library
  var m = utils.toBuffer(web3.sha3(message));


  var pub = utils.ecrecover(m, v, r, s);
  var sourceaddr = utils.pubToAddress(pub).toString('hex')
  if(sourceaddr == the_addr){
    console.log('Address 0x' + the_addr + ' owns this message.');
  } else {
    console.log('get out of town.  you dont own this');
  }



}

var run = function(){

  //our application

  createKeystore().then(generateKey).then( function(){
    //sign with address 1
    signSomething(addr1);

    //confirm that address 1 signed
    confirmAddress(addr1);

    //sign with address 2
    signSomething(addr2);

    //confirm that they don't match
    confirmAddress(addr1);
  });

}

run();

A Decaying Token - Building Catallax on Ethereum - Week 3

The last couple of weeks of chasing rabbit trails to try to figure out how to deliver pref payments out to accounts once a Catallax account has caught up has settled down this week due to making the following assumption:

An outside authority is going to have to keep track of and distribute pref payments.

I’ll get back to this in future development.  I may even find an on-chain solution, but until then I’m going to just table it and build out some of the other features.

Today I’m publishing some actual working solidity code that runs a decaying token.

You can see the contract at the bottom of this article or here:

https://gist.github.com/anonymous/7fc3f3a48ad3e8b26aa1a7c55030c64f

You can load it up in browser solidity here:

https://ethereum.github.io/browser-solidity/#gist=7fc3f3a48ad3e8b26aa1a7c55030c64f

I’ve stripped out the extraneous erc20 stuff and just focused on balances at the moment.  We are doing something pretty basic here.  We have a structure called a rateMap (mapping(uint -> Rate)) that is going to keep track of ranges of blocks and an associated decay rate.  If your account isn’t caught up to the latest maxCatchUpBlock, you can’t spend your tokens and must first ‘catch up’ before you can spend again.

In this example, we are trusting and outside authority to publish reliable rates and currently, the decayed tokens just collect in an internal variable in the contract(demurrageHold).

The Rate Struct looks like this:

struct Rate {
  uint256 nextblock;
  uint256 rate;
  bool initilized;
}

The nextblock variable points to the place in the rateMap mapping where you can find the next rate.  The initialized bool is used to validate that a rate that you have found in your rateMap is a valid rate.  Empty mappings will return an uninitialized struct so this lets us look up a rate and know that it is invalid.

When we start our contract we seed the rateMap like this:

//record the startblock that the currency came online -- used for cycling through rates
  startBlock = block.number;

  //create the first rate that goes from block 0 to the start block
  rateMap[0].initialized = true;
  rateMap[0].rate = 0;
  rateMap[0].nextblock = startBlock;

  //init the next rate
  rateMap[startBlock].initialized = true;

  //set the max catchup to the current block
  maxCatchUpBlock = block.number;

  rateBase = 10000000; //base used for rates.

So starting off we will have a rate from 0 to our startBlock of 0 and we will be waiting for the rate to be added with an initialized rate at the startBlock. 

You can observe the decaying currency by executing the following in browser solidity:

  1. Publish the contract with a call of 1000000000,””,2,””  - this creates a billion tokens and puts them in originator’s account.  Let’s assume this is 0xca35b7d915458ef540ade6068dfe2f44e8fa733c

  2. Note the startBlock variable and capture that.  We’re going to add our first decay rate by calling addRate with StartBlock, StartBlock + 100, 700000. Ie:  1150000,1150100, 700000 -Note that the rate we are putting in (700000) will be made a percentage by dividing by the baseRate Variable in our contract.  So in this instance we are decaying 7% over a 100 block period.  Pretty steep, but good for our example.

  3. Try transferring some tokens to another address by calling transfer(Ie:  "0x14723a09acff6d2a60dcdf7aa4aff308fddc160c", 100).  The function should throw since the maxCatchUpBlock has increased from our current maxCatcUpBlock for our original address of 0.

  4. In increase our catchUpBlock for our account we need to catch it up.  Call CatchUp with your account number.  Ie 0xca35b7d915458ef540ade6068dfe2f44e8fa733c

  5. Check your balanceOf your account and you should see that it is 70,000,000 tokens lighter.  These tokens are in the demurrageHold variable.

  6. Try your transfer from #3 above.  It should go through this time.

  7.  Notice that in the transfer we have to initialize the new account that is created with a catchUpBlock equal to the maxCatchUpBlock(1150100).  If we didn’t do this then the first time this account caught up it would start at block 0 even though it didn’t have any tokens from 1150000 to 1150100.

This token doesn’t do much except decay at a rate specified by the publisher.  There is a lot of work left to do, but it is nice to have some actual code that does something interesting.

Next week I’ll get back to putting some of the infrastructure necessary to issue out pref payments and maybe start looking at how to determine what those payments are processing the blockchain.

If you have any comments or questions, please leave them below. If you’d like to see more of this kind of stuff and help us build this new economy please consider supporting the "Catallax Code " patreon.

If this is interesting to you and you'd like to see where we are going with Catallax, please pick up my book Immortality.

Donations always accepted at:

BTC: 1AAfkhg1NEQwGmwW36dwDZjSAvNLtKECas

ETH and Tokens: 0x148311c647ec8a584d896c04f6492b5d9cb3a9b0

//© copyright 2017 - Catallax Bank and Rivvir Consulting
// Developed by Austin Fatheree
// http://catallax.info  @hypercatallax
// All rights reserved. 
pragma solidity ^0.4.8;

contract DecayToken {

struct Rate {
  uint256 nextblock;
  uint256 rate;
  bool initialized;
}

uint256 public totalSupply;
uint256 public startBlock; //holds the generation block for the contract so that we know where to start our linked list for decay rates
uint256 public demurrageHold;
uint256 public rateBase;
uint256 maxCatchUpBlock;

mapping(address => uint256) balance;
mapping(address => uint256) catchUpBlock;

mapping(uint256 => Rate) rateMap;

string public name;                   //fancy name: eg Simon Bucks
uint8 public decimals;                //How many decimals to show. ie. There could 1000 base units with 3 decimals. Meaning 0.980 SBX = 980 base units. It's like comparing 1 wei to 1 ether.
string public symbol;                 //An identifier: eg SBX
string public version = 'H0.1';       //human 0.1 standard. Just an arbitrary versioning scheme.



function () {
    //if ether is sent to this address, send it back.
    throw;
}

function DecayToken(
    uint256 _initialAmount,
    string _tokenName,
    uint8 _decimalUnits,
    string _tokenSymbol
){

  balance[msg.sender] = _initialAmount;               // Give the creator all initial tokens

  totalSupply = _initialAmount;                        // Update total supply
  name = _tokenName;                                   // Set the name for display purposes
  decimals = _decimalUnits;                            // Amount of decimals for display purposes
  symbol = _tokenSymbol;                               // Set the symbol for display purposes

  //record the startblock that the currency came online -- used for cycling through rates
  startBlock = block.number;

  //create the first rate that goes from block 0 to the start block
  rateMap[0].initialized = true;
  rateMap[0].rate = 0;
  rateMap[0].nextblock = startBlock;

  //init the next rate
  rateMap[startBlock].initialized = true;

  //set the max catchup to the current block
  maxCatchUpBlock = block.number;

  rateBase = 10000000; //base used for rates.
}

//erc20 interface
function balanceOf( address who ) constant returns (uint value){
  //todo: check validity
  return balance[who];
}

function transfer( address to, uint value) returns (bool ok){

  if(value == 0) throw;

  //test catch up
  if(catchUpBlock[msg.sender] < maxCatchUpBlock) throw;

  //make sure balance is positive
  if(balance[msg.sender] < value) throw;

  //update balances
  balance[msg.sender] = balance[msg.sender] - value;

  //if this is a new account or the previous balance was 0, catch it up by default
  if(balance[to] == 0){
    catchUpBlock[to] = maxCatchUpBlock;
  }
  balance[to] = balance[to] + value;


  Transfer(msg.sender, to, value);
  return true;
}

function addRate(uint _startBlock, uint _endBlock, uint amount) returns (bool ok){

  if(rateMap[_startBlock].initialized == false) throw; //a rate doesnt exist for this startblock

  if(rateMap[_endBlock].initialized != false) throw; //we cant correct rates here only append
  //set the new rate
  rateMap[_startBlock].nextblock = _endBlock;
  rateMap[_startBlock].rate = amount;
  rateMap[_endBlock].initialized = true;

  //update the maxCatchUpBlock for everyoune
  maxCatchUpBlock = _endBlock;
  return true;
}

function getRate(uint _startBlock) constant returns(uint _TheRate, uint _EndBlock){
  _TheRate = rateMap[_startBlock].rate;
  _EndBlock = rateMap[_startBlock].nextblock;
}

function catchup(address account) returns (bool ok){

  //todo: issuer can force catchup
  if(msg.sender != account) throw;


  uint transferAmount = 0; //the amount that will decay
  uint nextblock = catchUpBlock[account]; //lookup the current catchup block for this account
  uint startBalance = balance[account]; //lookup the current balance of an account

  //loop through each rate from the last catch up to maxCatchUpBlock and decay the cash
  while(nextblock < maxCatchUpBlock){
    Rate thisrate = rateMap[nextblock]; //what was the rate during this period?
    uint removeAmount = (startBalance * thisrate.rate)/rateBase; //calculate the amount
    transferAmount = transferAmount + removeAmount;  //store the amount
    startBalance = startBalance - removeAmount; //adjust balance used in calc so we don't go below 0
    nextblock = thisrate.nextblock; // update nextblock to advance loop
    //todo:  scheme to check remaining gas and bail if gas gets too low
  }

  balance[account] = balance[account] - transferAmount;  //update the balance
  demurrageHold = demurrageHold + transferAmount; //put the decayed amount into a place for everyone to see

  catchUpBlock[account] = maxCatchUpBlock; //update the catchup block allowing the account to spend

  CatchUp(account, maxCatchUpBlock, transferAmount);  //broadcast catchup so issuer can act
  return true;

}

event CatchUp(address indexed from, uint newMaxBlock, uint value);
event Transfer( address indexed from, address indexed to, uint value);

}

A week with Ethereum

The past week has been a fun one as I’ve started trying to actually write some ethereum code and figure out if the eco-system is ready for me to try to build on top of yet.  My very high-level priorities are currently:

  1. Figure out if I can build a decaying currency as prescribed by hypercatallaxy on ethereum.

  2. Figure out how to integrate this system with existing payment networks in a way that gives the Catallax card an unfair advantage over other kinds of payment networks.

  3. Figure out how to build the governance model as described in my book “Immortality” on the ethereum blockchain.

  4. Figure out how to transition from a “benevolent dictator” model to the created governance model in a trustless way that makes sense for system stability.

This week was all about #1.  I don’t have any code to post yet, but I did make some significant discoveries that I think will be productive:

Ethereum transactions are expensive.  

They are not as expensive as bitcoin transactions, but still expensive enough that building out all the infrastructure in blockchain storage is just not really an option at this point.  Writing a piece of data (address-> unit) looks like it can cost about $0.008. This is not that bad unless you are catching up and trying to send a couple dollars of demurrage to the 10,000 accounts that in your pref table.  Then all of a sudden you are updating 10,000 address -> uint pairs and this is going to cost you $80 to distribute $2 in decay.  This obviously won’t work right now.  Moore’s law says this probably won’t work for 12 years if gas costs track computing power.

Storing Data Off Chain

The solution looks like it may be storing data off chain.  Your pref map and even your balance may end up needing to be off chain in some trustless data structure.  TrueBit looks like the leader in the clubhouse here.  Because of the way hypercatallaxy works we should be able to structure code in such a way that current balances are deterministic given a set of transaction operators.  TrueBit lets any number of solvers run our code for us and update the blockchain.  If they try to lie, verifiers can force them to prove their calculations and take a large reward if they catch a cheater.  There are a bunch of things to work through here, but my current thoughts are that the Ethereum based part of the problem may end up just being a linked list of structs that track:

transactionType: uint (these will be coded in solidity based code so EVMs can run the transactions)

transactionHash: byte32 (this is a signature proving that the msg.sender created the transaction)

transactionLocation: byte32 (this is an ipfs hash pointing to a location where the json of the transaction detail can be publicly retrieved and verified with the has

I’ve just started thinking through this so there may be some more variable needed, but this kind of structure should get recording transaction down to a few cents and that is way more manageable.

If you have any insight or sample projects that have done this kind of structure where most of the data is kept off chain, let me know where to look.  Source code is a super bonus.

Next Steps:

I think I’m going to be learning a lot about Merkle Trees and roots and how those can be recorded once and then used as verification.


I’m also meeting with a card processing company that may have some insight on how I can set up goal #2. If nothing else I’ll have some expectation of the costs involved and be able to do some of the math necessary to figure out if the 0 transaction fee is going to be feasible or not.

Donations always accepted at:

BTC: 1AAfkhg1NEQwGmwW36dwDZjSAvNLtKECas

ETH and Tokens: 0x148311c647ec8a584d896c04f6492b5d9cb3a9b0

Rice's Business of the Blockchain Conference

This week I had the pleasure of attending the Rice “Business and the Blockchain” conference in Houston, TX.  It isn’t every day that we get a blockchain conference in Houston and it was really nice to get to see my kids and go to a conference in the same week for once.

I had two main agenda items at this conference:

Promote my new blockchain book “Immortality:  A moral and economic framework toward immortality” (more: http://catallax.info/news/2017/4/23/my-new-book-is-out-and-it-is-called-immortality).
Get caught up on the advances that ethereum has made in the couple of years that I’ve been distracted with my day job.

The first item went pretty well. I handed out a lot of cards.  I can now say that I won’t get skunked on my book sales.  I don’t think I’ll be on the New York Times bestseller list anytime soon, but what can you expect from a book on moral philosophy, economics, and a pie in the sky proposal for new money. I’m looking forward to getting feedback from those of you that bought a copy.

The second item was a success as well.  Of particular promise were the concepts of state channels and the many tools that ConsenSys are building to address real problems with the Ethereum blockchain.  Specifically, Infura and Uport look like they may have some specific applications to what I want to do with Catallax immediately.  Infura provides a number of support functions in the way that Gem does for BTC and Uport looks like it may be a great tool for collecting KYC data for banks that may operate on the Catallax system.

Overall the conference was run really well.  Everyone was well fed and the breakout session system for Q&A worked really well except when they would cluster 4 really great speakers together where I wanted to go to all 4 Q&As and then follow it up with 4 speakers that had less relevance for me.

A few action items came out of the meeting that have specific relevance for the next steps of Catallax and, specifically, the Catallax Card:

Start writing some contracts.  They don’t have to be perfect, but until the something is on paper I’m not going to be able to just learn by osmosis.
Research payment options.  Apparently, there are some new players in the payment space that may make issuing a card much more of a feasibility than it was before.
Review Contract Patterns.  The concept of an ERC20 token was thrown around quite a bit and I now know what that is.  Many folks are publishing their contracts (Augur has a set of 37 of them in their latest offering) and there is a lot to learn about the patterns being used.  If I have any insights I’ll publish them here.

I was less interested in many of the enterprise level integrations and my feeling is still that a good old database is sufficient for all but the most nefarious of consortia.  Blockchain is a great buzz word and if you can use it to sell some software to fortune 500 companies then more power to you.  Perhaps as I dig a little deeper I’ll see more relevance to the enterprise world.

If they run it again next year I’ll be back.  Hopefully next year we will be presenting Catallax as the next significant blockchain innovation.