Testing With Time - Dev Log 7

Weekly Update

  1. I’m a Dad again(for the fourth time).  Weston James was born on Tuesday evening June the 20th.  Mom and baby are healthy.  Big Bro, Big Sis, and Big Sis 2 are super excited, and Dad is really proud.
  2. I guess I’m a professional solidity developer as someone paid me actual money(well ETH) for the contract we are discussing today.  Not a lot, but enough be significant.
  3. Work continues on the whitepaper for the first service offering that Catallax will be trying to launch.  Lawyers, accountants, legalese, etc., etc.

Today we are going to do some testing with time.  The is going to be very important once we start testing our demurrage code.  In our decaying token we used passing block numbers to calculate our decay periods.  In the example today we are going to use the actual time system in Ethereum.  This system isn’t an exact science since we are somewhat dependent on the Miners to give a truthful timestamp on each block.  You would not use this system if you were doing calculations on short time scales because a miner could attempt to cheat your contract.  Our example today uses month long periods so we should be fine using time.
 
The contract we are going to develop is called a DisciplineWallet.  Do you have lambo money from buying into the ethereum crowdsale two years ago?  Afraid you’re going to get spooked and sell?  Use the DisciplineWallet and restrict access to your ETH on a monthly basis.
 
When we first started talking about this contract the client wanted the payout to be consistent in USD.  We went back and forth and finally decided that we needed to do it in ETH because there isn’t really a good USD to ETH Oracle that is reliable over long periods of time.  If you know of one, please let me know and I’ll try to update this contract to do USD instead.
 
Our contract will do the following:

  • Be initialized with a term in months and an amount of ETH to pay out each month
  • Take Deposits in ETH
  • Expose a Withdraw function that can be called once a month to send the specified amount of ETH to the owner of the contract
  • Let us change the owner of the contract
  • Withdraw all the remaining ETH to a specified address once the term has run its course
  • Give us a safety function to move coins out of the contact if we accidentally send ERC20 tokens to the contract
  • Use the fallback function as a deposit function
  • Tell us when the next withdrawal is available

Once we write up our contract we are going to want to test it.  To do this we are going to need a blockchain environment that will let us make time go by quickly. Fortunately, the testrpc that is packaged with the truffle dev environment lets us do this with the following call:

web3.currentProvider.sendAsync({
       jsonrpc: "2.0",
       method: "evm_increaseTime",
       params: [86400 * 34],
       id: new Date().getTime()
     }


In the above example, we are moving the clock forward 34 days(86400 seconds in a day).  Our tests will do withdrawals and then move the clock forward and do withdrawals again.
 
Our contract will need to pass the following tests:
 
    ✓ should Deploy a wallet with owner (91ms)
    ✓ should be off when it starts and has no ether (69ms)
    ✓ should have a function Period that returns the length of a month (102ms)
    ✓ should have a function NextWithdraw that returns the first withdraw time (94ms)
    ✓ should turn on when sent ether (775ms)
    ✓ should fail if constructor sent ether
    ✓ should allow withdraw after 1 month and ether goes to owner (750ms)
    ✓ should fail on instant withdraw (255ms)
    ✓ should not allow more than term number of withdraws (955ms)
    ✓ should not allow withdraw if some time has passed, but not enough (382ms)
    ✓ should allow withdraw all after term is over (3389ms)
    ✓ should fail if withdrawAll is called before term is over (388ms)
    ✓ should reject payment if payout term is expired (2778ms)
    ✓ should deposit using deposit function (245ms)
    ✓ should allow for transfer of owner (1529ms)
    ✓ should reduce payout if payout would drain account before the end of the term (679ms)

The code and truffle set up can be found on GitHub here. 
Here is our contact.

pragma solidity ^0.4.11;

contract DisciplineWallet {

  /**
  * @dev term is the number of months that a wallet will pay out
  */
  uint16 public term;


  /**
  * @dev currentTerm tracks the number of withdraws that have occured
  */
  uint16 public currentTerm;

  /**
  * @dev contractStart stores the timestamp(number of seconds since 1/1/1970) that the contract was created
  */
  uint public contractStart;

  /**
  * @dev payout is the number of wei(smallest unit of ETH) to pay out
  */
  uint public payout;


  /**
  * @dev bActive is tracks if the wallet is open for business or not
  */
  bool public bActive;
  address public owner;

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    if (msg.sender != owner) {
      throw;
    }
    _;
  }

  /**
   * @dev constructor
   * @param termLength number of months that the contract will be active
   * @param weiOutputPerPeriod of wei to pay out
   */
  function DisciplineWallet(uint16 termLength, uint weiOutputPerPeriod) {

    if(termLength < 1) throw; //term cant be 0
    if(weiOutputPerPeriod < 1) throw; //we cant pay out 0

    //the owner will start as the address creating the contract
    owner = msg.sender;

    //set the term
    term = termLength;

    //record the time of the start contract
    contractStart = now;

    //start with the current term as 1
    currentTerm = 1;

    //set the payout per period
    payout = weiOutputPerPeriod;
  }


  /**
   * @dev calculates the length of a month
   */
  function Period() constant returns (uint32 lengthOfMonth){
    //put this in a constant function so that we don't have to use storage
    //execution takes 302 gas which means calculation is more efficent in any contract under 66 months.
    //not sure about deployment costs
    //the period is about 30.66 days so that leap year is taken into account every 4 years.
    return (1 years / 12) + (1 days / 4);
  }

  /**
   * @dev tells us what date we can call the withdraw function
   */
  function NextWithdraw() constant returns(uint secondsAfter1970){
    return contractStart + (Period() * currentTerm);
  }

  /**
   * @dev the fallback function will make a deposit
   */
  function () payable{
    Deposit();
  }

  /**
   * @dev Put ETH into the contract, also called by the fallback function
   */
  function Deposit() payable {
    //don't accept ether if the term is over
    if(currentTerm > term) throw;
    if(bActive == false){
      //first time we get ether, turn on the contract
      bActive = true;
    }
  }

  /**
   * @dev Withdraw will send the payout to the owner if enough time has passed
   */
  function Withdraw() onlyOwner returns(bool ok){
    if(currentTerm <= term && now > NextWithdraw()){

      //payout may not be more than balance / term or the account has been underfunded
      //if it is then use the lower calculatio
      if(payout < (this.balance / (term - currentTerm + 1))){
        owner.transfer(payout);
      }
      else{
        owner.transfer(this.balance / term);
      }

      currentTerm = currentTerm + 1;

      if (currentTerm > term){
        bActive = false;
      }

      return true;
    } else{
      throw;
    }

  }


  /**
   * @dev once all terms have expired you can move any remaining ETH to another account
   * @param targetAddress The address to transfer remaining ETH to.
   */
  function WithdrawAll(address targetAddress) onlyOwner returns(bool ok){
    if (targetAddress == 0x0) throw; //dont accidentally burn ether
    if(currentTerm > term && this.balance > 0){
      targetAddress.transfer(this.balance);
      bActive = false;
      return true;
    } else {
      throw;
    }

  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) onlyOwner {
    if (newOwner != address(0)) {
      owner = newOwner;
    }
  }

  /**
   * @dev Allows the owner to send tokens elsewhere that were accidentally sent to this account
   * @param Token The address of the ERC20 token
   * @param _to The address the tokens should end up at
   * @param _value The amount of tokens
   */
  function safetyTransferToken(address Token, address _to, uint _value) onlyOwner returns (bool ok){
    bytes4 sig = bytes4(sha3("transfer(address,uint256)"));
    return Token.call(sig, _to, _value);
  }

}


The tests are in CoffeeScript and can easily be compiled to js. The core test concept here is the passage of time.
 
In the "it should allow withdraw after 1 month and ether goes to owner" test we simulate the passing of 34 days via our testrpc evm_increaseTime function mentioned earlier.

Our test code needs to do this multiple time over a set amount of time.  I use a variant of the following function:

withdrawFunction = ()->
  return q.Promise (resolve, reject)->
    web3.currentProvider.sendAsync
      jsonrpc: "2.0",
      method: "evm_increaseTime",
      params: [86400 * 34],  # 86400 seconds in a day
      id: new Date().getTime()
    , (err)->
      i.Withdraw(from: accounts[0])
      .then (result)->
        resolve result
      .catch (err)->
        reject err

We can call it in a loop like this:

async.eachSeries [1..13], (item, done)->
        #console.log item
        withdrawFunction()
        .then (result)->
          i.currentTerm.call(from: accounts[0])
        .then (result)->
          #console.log result
          done()
        .catch (err)->
          #console.log err
          done(err)
    .then (result)->
      assert(false, "shouldnt be here")
    .catch (error)->
      if error.toString().indexOf("invalid op") > -1
        #console.log("We were expecting a Solidity throw (aka an invalid op), we got one. Test succeeded.")
        assert.equal error.toString().indexOf("invalid op") > -1, true, 'didnt find invalid op throw'
      else
        assert(false, error.toString())
  done()

In the above case we call withdraw 13 times and expect it to fail on the 13th try.
 
We now have a great way to test the passage of time when testing our solidity contracts.  Since Catallax will likely do monthly this avenue of calculation may work.  We could manipulate our Decay Token to use timestamps instead of block numbers.  On the other hand, using block numbers allows us more control if we need to do some emergency decay as a monetary lever.

If this is interesting to you and you'd like to see where we are going with Catallax, please pick up my book Immortality(Purchasing a hard or kindle copy helps support this project.

Donations always accepted at:

BTC: 1AAfkhg1NEQwGmwW36dwDZjSAvNLtKECas

ETH and Tokens: 0x148311c647ec8a584d896c04f6492b5d9cb3a9b0

Privacy, Accounts, and Transparency

This is the third part in a five part series of posts that lay out the basics of what we are trying to build with Catallax.  The series will follow the following schedule and I’ll update the list with links as the articles go live:

  1. Demurrage, Catch Up, and Pref Dividends
  2. Passthroughs, Legacy, and Folding the Blockchain
  3. Privacy, Accounts, and Transparency  (today)
  4. Selective Citizenship and Citizen Override
  5. Loans and a new kind of Capitalist

 Privacy is a very important issue.  It is also an issue that is very hard to predict.  It is possible that in the future we will have a very hard time maintaining privacy for anyone when computers and data are involved.  This has caused me to think about a few questions in regards to Catallax and how to move forward with privacy in mind.

 
How can we be long privacy in the places we want it?
How can we be short privacy in the places we don’t want it?
How can we reduce the need for privacy by increasing the value of transparency?
 
Let’s first talk about the elephant in the room.  Catallax in its rawest form lacks any kind of privacy.  It tracks who you spend money with, who spends money with you, and publishes that info on a public blockchain. Yikes.  This is a privacy nightmare.
 
So let’s unpack this and see how it isn’t that bad.
 
The first step we take is by making transparency really valuable.  The scenarios given in part 1 show how by making your transactions open you can reap varying levels of financial reward for the sacrifice in privacy.
 
A scenario that I regularly compare this to is the ownership of stock.  Chances are that if you own stocks you don’t own them anonymously. You want your name(or at least your account number) next to those certificates so that they well send you dividends when they pay out.
 
Catallax’s first step in addressing these issues is by making it more valuable give up some privacy than to keep it.
 
With that in mind, there are still situations where you do NOT want to forfeit your privacy.  For example, there may be a medicine you need for an undisclosed medical condition and you don’t want the public to know you are buying it.  For those situations, we propose a system of privacy pools.  The privacy pools will allow you to send cash into a vague account and have it anonymously end up in the account you want it to go to.  This is a technical challenge but I think is achievable by using zkSnarks. This is a core feature coming to a future version of ethereum.  These pools will still operate in a catallaxy way where cash will flow from receivers into the pools and out to payers via a pass through, but the payments will be less associated with the payer’s ability to spend money wisely.
 
We further address privacy by splitting accounts into contexts, each of which has a specific privacy profile:
 
Citizen Accounts:  real people can send and receive private payment
 
Legal Entity Accounts: businesses with limited liability must sacrifice some privacy for the right to limited liability.  They can receive private payments, but cannot send them.
 
Government and Institutional Accounts:  These accounts can collect taxation from the system and as a consequence must be completely transparent.  They cannot make or receive private payments.
 
These accounts and their subtypes are discussed more in the Form Language section of my book Immortality (buying a physical or kindle copy helps support this project).
 
This privacy signature is currently a proposal and I’m very interested in speaking with experts on the gaps I’ve left.  I think that the current proposal address privacy where it is important and adds significant anti-corruption infrastructure where it is needed for a free and open society to develop.

If this is interesting to you and you'd like to see where we are going with Catallax, please pick up my book Immortality (Purchase of a physical or kindle copy helps support this project).

Donations always accepted at:

BTC: 1AAfkhg1NEQwGmwW36dwDZjSAvNLtKECas

ETH and Tokens: 0x148311c647ec8a584d896c04f6492b5d9cb3a9b0

If you would like more code articles like this please consider becoming a patron on patreon.

Next: Selective Citizenship and Citizen Override
 

Happy Birthday, Catallax!

Note: The Dev Log will return next week and we’ll be looking at testing time in truffle + testrpc. I’m on vacation this week. Enjoy this brief history post in its stead.

This week is the three year anniversary of the concept behind Catallax.  Every year my family and I take a retreat into the east Texas woods to relax and rejuvenate. This place is great and there is a ton of child care so that parents can reconnect and have some time to step away from the children.
 
Three years ago I had a really great confluence of influencers. We had just found out that our third child was on the way and I was deep in the weeds with Piketty, Fukuyama, and wrestling them through the lenses of Alexander.
 
I had been thinking for a long time about how money fell short of all that I thought it could be. I distinctly remember drawing a dollar with arrows over it going both directions in the early 2000s. I was introduced to Kevin Phillips’ History of the American Rich and I banged my head against the problem a good bit, but never came up with much.
 
In 2009 I discovered Gesell and his natural money concept. That discovery really clicked a few things into place and there was something about the 0% interest assumptions that I knew was going to be important. I wrote a piece of fan fiction about one of the big cell phone makers launching a natural money to fix the economic crisis. It never really went anywhere.
 
It wasn't until June of 2014 that Bitcoin and the Blockchain came into the picture and clicked all the pieces into place.
 
Lessig's mayday PAC was flailing and the prospect of never being able to fix money in politics led to a deeper question of how can we fix money.  Piketty showing the data of capital concentration magnified many of the principles that I'd been ruminating on since I'd read Phillips a decade and a half earlier. On a morning walk, a number of ideas were elevated into RAM out of the cold storage of my brain. Bitcoin's idea of a public ledger of all transactions was a key piece in the puzzle. Before seeing and understanding that this was a tech that could actually live in the world Catallax would not have been possible.
 
It wasn't until later that year that I got into the meat of the Bitcoin tech and realized that all the pieces I needed were already there, but the summer of 2014 caused me to start writing the pattern language found in my book Immortality. 
 
I tried to soft launch in 2015 with a talk at the Texas Bitcoin Conference and flying to NYC to demo at the Singularity Institute's Exponential Finance.  The feedback was ok, but not what I wanted. In that same season, a colleague brought a business opportunity to me that was too good to pass up. We bought a company in an unrelated field and we've been fighting the good fight trying to apply new technologies to the world of organ donation for the last two years.  It has been a fun ride and we are starting to see enough light at the end of the tunnel that I can start to hand some of my responsibilities over to new employees. 
 
I haven't been completely idle. As I've been crisscrossing the country installing software at organ centers I've been piecing together the book Immortality that lays out why I think we need this new kind of money. "Why?" Was the biggest question I received when I had tried to launch previously.  Somewhere around early 2016 Robert Pirsig helped me answer that question in his amazing book Lila.  I hope that if you have the “Why?” question and that the intersection of moral philosophy and economics piques your interest that will check out Immortality and that it will answers that question.
 
During the last two years, ethereum has really matured and now seems to be the platform that I needed all along. Now we are here in the summer of 2017 and people are paying me to write solidity contracts. The pieces of the puzzle for how Catallax can be a real thing now are starting to fall in place and the last few hurdles of regulatory compliance are being arranged.  Please follow us on twitter, medium, rss, Facebook, or Reddit and come along for the ride.
 
Let's fix money.
 

Happy Birthday, Catallax!

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

If you would like more code articles like this please consider becoming a patron on patreon.

Get to know Catallax: Passthroughs, Legacy, and Folding the Blockchain

This is the second part in a five-part series of posts that lay out the basics of what we are trying to build with Catallax.  The series will follow the following schedule and I’ll update the list with links as the articles go live:

  1. Demurrage, Catch Up, and Pref Dividends

  2. Passthroughs, Legacy, and Folding the Blockchain (today)

  3. Privacy, Accounts, and Transparency

  4. Selective Citizenship and Citizen Override

  5. Loans and a new kind of Capitalist

The blockchain is really an amazing invention.  We’ve had public books and public ledgers for a while, but having one that is unchangeable is a really amazing evolution.  Catallax will use this ledger to help reduce the risk of investment.  We anticipate this will accelerate the flow of capital to riskier ventures than the market will currently bear. 

The mechanism is to do this is called ‘folding the blockchain’.  As we mentioned in part 1, we are going to have a backwards flow of pref payments going from accounts that have received cash to those that have paid in cash.  Because we want this money to flow efficiently we need to handle a couple of scenarios so that our cash doesn’t get ‘stuck’ in the system.

The first situation to handle is the death of an account holder.  To handle this we can mark an account as a ‘passthrough’  account.  This has a couple of effects.  The first is that any pref payments that come into this account will pass through directly to pref owners in the account without having to wait around for Catch Up.  The second is that this passthrough will avoid any sort of taxation.  We will talk more about taxation in part 4 of this series, but for now just know that it is possible for these pref payment flows to be taxed.  By marking an account as passthrough we are creating a temporary ‘folding of the blockchain’ that keeps our cash flowing efficiently.  For individuals, pass-through will be a temporary feature while an account is in the probate process.

Eventually, these accounts can be completely dissolved via a legacy platform that is just in the beginning stages of development.  The guiding principle is to hold a long/short position on becoming wealthy.  We want to reward the legacy of individuals while guarding against capital concentration.  I will not go into much more detail about this here but you read more in the Legacy chapters in my book Immortality (Buying a physical/kindle copy helps support this project). 

A similar process of passthrough/probate legacy can be implemented for legal entities in a way that drastically reduces the risk of investment in new ventures.  To understand how this works let’s look at the following scenario:

Susan wants to start a company to compete with facebook.  She has a great mvp and some sort of unfair advantage that makes it a possibility that she could compete. It is still a risky venture and Susan is only able to find one Venture Capital firm that will fund her. Venture Co. agrees to invest $1 million catallaxian bucks in Susan Co.  Susan takes the cash infusion and spends the money on:

Bob, a developer: $100,000

Amazon Web Services $500,000

Real Co., An office leasing company $50,000

PR Co., A PR firm that handles their advertising, $350,000

After a year Susan Co. decides that they had a failed proposition. They have yet to earn a dime and are out of cash.  Poor Susan Co.  And Poor Venture Co. Their investment is now worth nothing except what they can get for the tech that Bob developed.  But in a Catallaxian economy, their downside is somewhat limited.

By dissolving Susan Co and ‘folding the blockchain’ over the company, the prefs that Susan Co. owned in Bob, AWS, Real Co., and PR Co. can be given to Venture Co.  All of that cash went somewhere, and because of the blockchain, we know exactly where it went.  Venture Co. has their risk reduced by the cash that flows back to them from these four organization over the next X years.  X is dictated by how fast their pref position in these organizations is diluted. 

If PR Co. goes on to be a billion dollar PR firm, Venture Co. could end up making back their entire investment.

In a traditional economy, when the money is gone it is just gone.  As a result, investors tend to look for a certain risk profile.  Innovation is driven in some proportion by the risk investors are willing to take.  By reducing the risk profile of investments we should be able to accelerate the rate of innovation.

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

If you would like more code articles like this please consider becoming a patron on patreon.

To Part 3:  Privacy, Accounts, and Transparency

Calling Future Contracts from Contracts in Ethereum - Dev Log 6

Quick Updates:

  1. I’m going to plug the Blockchain Show one more time as I was on last week and it is a great way to get an intro into some of the highlevel concepts of Catallax.
  2. There was an awesome turnout at the Houston Bitcoin Meetup this week.  I think it was the biggest one yet.  I guess the attendance tracks the price.  Topics of discussion include "What are you working on?" A: Catallax on Ethereum" to "How are you learning?" A: Lots of stack exchange and writing crappy code.

Code:

On to the code for this week and this one is a doozy.  

After building my FunkyCoin wallet last week I realized a pretty big flaw.  Having a wallet is kind of useless if you need to transfer your coin and/or ETH back to a real address before you can interact with a contract.  For example, our FunkyCoin wallet couldn’t buy an ENS domain name because it doesn’t know the code signature of ENS.  We could include the code interface in our Wallet contract, but if wanted to include every service our code would get huge.  And worse, what if someone builds an amazing service next week that runs on FunkyCoin?  Everyone with an existing wallet would have to deploy a new wallet with the new code signatures and transfer their FunkyCoin to it.
 
I may be missing something major so please reach out to me if I’m bungled something up. This seems like a pretty big use case flaw in ethereum. So...I went looking for a solution.  And...I think I found one.
 
Warning:  From what I understand what I’m about to do appears to be recommended against by most who have written even a little bit about this topic.  Use at your own risk.
 
Goal:  Write a contract that I can own that can call any other contract that may come online in the future.
 
It turns out there is a way to call code and contracts that you don’t really know about from a contract.  This is accomplished by using the CALL feature of solidity.  The best documentation I could find on it is here under the members section, but that seemed to be a bit incomplete.
 
If you have an address A in your solidity contract and A is a contract, you can call one of its functions by doing:
 
    A.call(the_contract_signature_signature, [optional: a, set, of, parameters])
 
The stuff that isn’t documented very well that found were the following:
 
The param the_contract_signature_signature looks like “bytes4(sha3(“MyFunction(address,uint256)”))”  where the param items are pretty specific.  I didn’t explore the whole scope of value types, but I did find out that uint doesn’t work...you need uintXXX where XXX is the byte length.  Also, if your function has no arguments it needs to be “MyFunction()”.  What you end up with here is a 4 byte signature that points to the function in the contract.  Apparently, to save space the full function name isn’t used and they use the sha3 to guarantee uniqueness.  Only taking the first 4 bytes probably could lead to some collisions, but maybe not.  There is probably a function that calculates this.  Have fun chasing down that bug if it ever happens.
 
The [a, set, of, parameters] is just a list of params where each one is the hex representation of byte32 padded on the left.  So an address of 0xa845e57fcc55024711da2652b6956e9f72a252fe becomes 0x000000000000000000000000a845e57fcc55024711da2652b6956e9f72a252fe and the number 11 becomes 0x000000000000000000000000000000000000000000000000000000000000000b.  I did not test strings and I’m not sure what you would need to do if your string goes over 32 bytes.  Maybe this is disallowed in ethereum?
 
Using this function we are going to create an escape hatch function into our contract that allows us to call arbitrary code in other contracts as if we were the contract.  I think that this would be an alternate solution to the ERC20 bug and ERC223 solution where people are sending coins to contracts and they get stuck.  A contract doesn’t have a primary key so you can't just construct a function call for it because you can’t sign the transaction as if you are the contract.  If you call the contract and then it calls something I think the pk is baked in so things work.
 
The one drawback is that the CALL function doesn’t return the return value of the function you call.  It returns true or false.  False is thrown if the other contract throws, so you always need to check this value and throw if you get false.
 
HELP NEEDED:  If you know of a way to inspect the blockchain to determine what the actual return value of this call was, please reach out to me and explain.  I don’t necessarily need this value in real time, but since the blockchain is deterministic it seems like we should be able to find it once the transaction block is committed to the chain.
 
In theory, this setup should work.  So let’s take a look at the function in our BeepBopBot that will be our digital selves on the blockchain:

Gist here

Load in Remix Here
 
 

contract BeepBopBot {

    address public owner;
    bytes32 emptyBytes;

    event Impersonation( address indexed caller, address indexed executer, string functionSig);

    function BeepBopBot(){
      owner = msg.sender;
    }

    function impersonate(address aContract, string functionSig, 
        bytes32 _1,
        bytes32 _2,
        bytes32 _3,
        bytes32 _4,
        bytes32 _5,
        bytes32 _6,
        bytes32 _7,
        bytes32 _8) returns (bool ok){

        bool result = false;
        bytes4 sig = bytes4(sha3(functionSig));

        if(_8 != emptyBytes){
            result = aContract.call(sig, _1, _2, _3, _4, _5, _6, _7, _8);
        } 
        else if(_7 != emptyBytes){
            result = aContract.call(sig, _1, _2, _3, _4, _5, _6, _7);
        }
        else if(_6 != emptyBytes){
            result = aContract.call(sig, _1, _2, _3, _4, _5, _6);
        }
        else if(_5 != emptyBytes){
            result = aContract.call(sig, _1, _2, _3, _4, _5);
        }
        else if(_4 != emptyBytes){
            result = aContract.call(sig, _1, _2, _3, _4);
        }
        else if(_3 != emptyBytes){
            result = aContract.call(sig, _1, _2, _3);
        }
        else if(_2 != emptyBytes){
            result = aContract.call(sig, _1, _2);
        }
        else if(_1 != emptyBytes){
            result = aContract.call(sig, _1);
        }
        else {
            result = aContract.call(sig);
        }
        if(result == false) throw;

        address theSender = msg.sender;
        Impersonation(theSender, this, functionSig);
        return result;

    }
}


So a couple things you should notice off the bat:

  • This is really ugly and there is probably a better way to this.
  • You probably want to use an owner only throw at the top of this so that only the owner can use this escape hatch.
  • You probably also want to make sure that the contract isn't callin it self.  If you called Impersonate on your own contract you'd eventually run out of gas.
  • We are limited to 8 parameters so if a future contract has more than 8 we won’t be able to call it with this contract.
  • This contact doesn’t do much except impersonate, but it could be added to pretty much any contract as an escape hatch.
  • I have no idea about the gas costs of this and I may just be burning all kinds of gas.
  • You will see that we are broadcasting an Impersonation event that I’m hoping I can hook to and find function returns after the transaction is committed to the blockchain.

 
Now that we have something that should in theory work, how can we test it?  To do this I’ve created a simple Name registration service that lets you claim addresses as yours.  When you claim an address a new NameObject contract is created and you are set as the owner.  You can then trade around the NameObject to others.  It doesn’t do much but help us prove our point.
 
A real world application would be creating a multisig wallet that is able to bid on an ENS name, claim it, hold it, and interact with it.
 
Here is our simple service:
 

contract NameService {

    mapping(address => address) public addressContracts;
    uint public coolNumber;

    event NameReserved(address indexed caller, address indexed nameObject);


    function NameService(){
        coolNumber = 12;
    }

    function lookUp(address theAddress) constant returns(address contractAddress){
        return addressContracts[theAddress];
    }

    function Claim(address theAddress) returns (address aName){
        if(addressContracts[theAddress] != 0) throw;
        address anAddress = theAddress;
        aName = new NameObject(msg.sender, anAddress);
        addressContracts[theAddress] = aName;
        address theSender = msg.sender;


        NameReserved(theSender, aName);
        return aName;
    }

    function ClaimSet(address theAddress, uint256 aCoolNumber) returns (address aName){
        //note the uint256, uint didn't work

        if(addressContracts[theAddress] != 0) throw;
        coolNumber = aCoolNumber;

        return Claim(theAddress);
    }

    function FindCoolNumber() returns (uint256 aNumber){

        aNumber = coolNumber;
        return aNumber;
    }


}

contract NameObject{

    address public owner;
    address public claimedAddress;
    bool public hereIam;

    event IExist(address owner);
    event Transfered(address owner);



    function NameObject(address aOwner, address aClaimedAddress){
        owner = aOwner;
        claimedAddress = aClaimedAddress;
    }

    function ProveExistance() returns (bool ok){
        hereIam = true;
        IExist(owner);
        return true;
    }

    function Transfer(address __newOwner) returns(bool ok){
        if(msg.sender != owner) throw;
        owner = __newOwner;
        Transfered(owner);
        return true;
    }
}

I have actually deployed and tested this on the Ropsten contract.  Here are the steps that I followed and the transaction numbers:

Create our BeepBopBot:

Txn: https://ropsten.etherscan.io/tx/0x1d441c4196ebf049e52f893002ac267035c7bece43cedd8be4bc3b1784a384fc

Resulting contract: https://ropsten.etherscan.io/address/0x38a31dbad2448286b3687363e72bb21f96ccbe56

Create our NameService:

Txn: https://ropsten.etherscan.io/tx/0xc1685751f4ad3879ff18be828d404c55183790184b4a6a2738ed812efbd1818b


Resulting contract: https://ropsten.etherscan.io/address/0x71c253362a44bed4b85ac21d1274dd4f7fd9d516

Try to find the Cool Number from the NameService as BeepBopBot.  It should be 12:

 Call:  BeepBopBot.impersonate("0x71c253362a44bed4b85ac21d1274dd4f7fd9d516","FindCoolNumber()")

Txn: https://ropsten.etherscan.io/tx/0x4a49418a8999b73818fdf0ca2f9226934f6869bd50a43042bec9f032c4178113
 
Not much happens in this call except that an Impersonation event is generated.  The actual cool number is lost to the ether(pun intended).
 
Help Needed:  I can assume that when BeepBopBot called FindCoolNumber that 12 was returned because that is what it was set to when the contract was created.  Is there a way to verify that?  Replay it?  What tools would I use?  How would I isolate it?

Try to claim and address as BeepBopBot:

 Call: BeepBopBot.impersonate("0x71c253362a44bed4b85ac21d1274dd4f7fd9d516","Claim(address)","0x000000000000000000000000a845e57fcc55024711da2652b6956e9f72a252fe"

Txn: https://ropsten.etherscan.io/tx/0x7a350203f4d0ad2f1d5af4515213b71f7af114573ac9a55eeae8ddda712e8521

Contract Created: https://ropsten.etherscan.io/address/0xf8A7141Dd1341b013808b4f583C32ACb3345DebA
 

If I look at the transaction on etherscan it shows me that an internal transaction created a new contract at 0xf8A7141Dd1341b013808b4f583C32ACb3345DebA. I’m hoping that this is my new name object and that BeepBopBot is the owner.
 
We can check the value of our cool number by using https://www.myetherwallet.com and clicking on the contracts tab.  Switch over to the ropsten network using the network selector in the top right.  Enter our 0x71c253362a44bed4b85ac21d1274dd4f7fd9d516 address for our deployed Name service and copy the ABI from the solidity contract in remix / browser solidity.  We can see that our cool number is now nine!  We didn’t put much security on this thing so anyone can change the number by claiming and address with ClaimSet.
 

Try to claim an address and set the cool number as BeepBopBot:

We are going to claim another address, this one is just one off of the last(ff instead of fe on the first param)
 
Call: BeepBopBot.impersonate("0x71c253362a44bed4b85ac21d1274dd4f7fd9d516","ClaimSet(address,uint256)","0x000000000000000000000000a845e57fcc55024711da2652b6956e9f72a252ff","0x0000000000000000000000000000000000000000000000000000000000000009")

Txn: https://ropsten.etherscan.io/tx/0xf5d3a25647798d1b974d21ce6981b1f612db87f609b953375e7a02eda0f5ecb2

Contract Created: https://ropsten.etherscan.io/address/0x7169576471f3067e51bafb2bfe0816e4c6580cdc

Checking in MEW:

 

Make sure that FindCoolNumber now returns 9:

 Txn: https://ropsten.etherscan.io/tx/0x0c058b8be54b5f847b7feb41e5d883bb8defb11ed6bdbee8c3445c1903778e1b
 

Prove Existence of my NameObject

This should set a bool in one of my new NameObject contracts.  I’d like to actually see this data, but for now I’ll assume it is working correctly.
 
Call: BeepBopBot.impersonate("0xf8A7141Dd1341b013808b4f583C32ACb3345DebA","ProveExistance()")

Txn: https://ropsten.etherscan.io/tx/0x940f8e464a12123411b4d86165df65eec165c5e16c646bd2d2269de70d5c26a3
 

Try to transfer my NameObject to a different Owner:

Call: BeepBopBot.impersonate(“0xf8A7141Dd1341b013808b4f583C32ACb3345DebA","Transfer(address)","0x000000000000000000000000a845e57fcc55024711da2652b6956e9f72a252f9")

Txn: https://ropsten.etherscan.io/tx/0x71104e8e69ee023799599224fb3491c906f51294c9a79615dec0f5d10baff04d
 
Try it again and it should fail because we are no longer the owners
 
Call: BeepBopBot.impersonate(“0xf8A7141Dd1341b013808b4f583C32ACb3345DebA","Transfer(address)","0x000000000000000000000000a845e57fcc55024711da2652b6956e9f72a252f9")

Txn: https://ropsten.etherscan.io/tx/0xb4e20d75033bc5e9c7fff3bdfe30d376b802995c7557e7a3a751b24ab93b318c

If you inspect the above transaction you will see that it threw as we were expecting.
 
It looks like our system works!
 
In summary here are the things left to solve:

  • Can we deduce the return value of impersonated functions from the blockchain?  If not directly can we replay them and pull the value out?  How?  This is important if some of these functions are returning created hashes or other important data for the contract.
  • If we make the impersonate function payable, does sent ETH flow through the contracts properly?  This would be important if you were sending ETH to an ICO auction in the name of a multisig wallet.
  • Is there a better signature for the impersonate function?  Right now if one of your params is 0 none of the other params after it will be sent.  This is probably an easy fix of adding the param number to the impersonate function, but there are probably other ways of doing this and probably much more efficient assembly level code that could do the same thing.

 If you have any answers to these questions please reach out to me at @hypercatallax on twitter or on our r/Catallax reddit.  You can also take a crack at these stack exchange question:
 
https://ethereum.stackexchange.com/questions/17368/can-i-get-the-return-value-of-a-call-from-a-contract-from-the-blockchain
 
 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

If you would like more code articles like this please consider becoming a patron on patreon.

 
 
 
 

Get to know Catallax: Demurrage, Catch Up, and Pref Dividends

This is the first part in a five-part series of posts that lay out the basics of what we are trying to build with Catallax.  The series will follow the following schedule and I’ll update the list with links as the articles go live: 

  1. Demurrage, Catch Up, and Pref Dividends (today)

  2. Passthroughs, Legacy, and Folding the Blockchain

  3. Privacy, Accounts, and Transparency

  4. Selective Citizenship and Citizen Override

  5. Loans and a new kind of Capitalist

Demurrage, Catch Up, and Pref Dividends

The hook of this system is built on Silvio Gesell’s concept of Natural Money as described in his book ‘The natural economic Order.'

Natural money is ‘natural’ because it decays like all kinds of real capital. Historically, this kind of money was implemented using stamped money.  With stamped money you would have to buy a stamp(say for 1 cents) and affix it to your physical $1 bill once a month(thus having a 12% decay rate).  At the end of each year, all bills would be turned in for new bills. Stamps are a bit impractical in the real world and we are able to do away with them because of the blockchain.  Instead of charging for a stamp, we just track the decay rate and make sure that each account that uses the system pays the correct fee before they are able to transfer money.  We call this the Catch-Up.  I’ve laid out a simple way to do this in solidity in a dev log post.

This is a decent system for accelerating the flow of cash through an economy.  If you cash is going to decay you want to quickly find a place to spend/invest it so that someone else takes on the burden of paying the decay fee.  You will typically find people willing to pay the fee in exchange for reducing risk elsewhere.  As a result, your cash ends up being more efficient as a liquidity tool. 

Implementing a decaying currency is all well and good, but what to do with the decay?  Other blockchains have tried allocating this a miner reward friecoin.  In other stamped money systems the decay fee was used to provide government services and treated like a tax.  We are going to do something different with our decay fees.  We are going to treat the blockchain as a time machine and pass the decay backward through the blockchain to the people that paid into an account.  We call these Pref Dividends.  By doing this we not only incentivise the application of cash so one does not have to pay the decay fee, but we incentivise the application of cash to destinations that the cash holder anticipates will be good at attracting more cash in the future.

Let's take a look at a couple of examples of how this system would work.

Scenario 1 - The Wine Heiress:

A wine merchant produces a bottle of stunning wine.  I think this bottle of wine is worth $20 and the merchant agrees.  This is her first catallaxian transaction so when I give her $20 for the wine, I get 20 pref shares in her account.  I own 100% of the pref shares at this point.  The next day she finds out that a Catallaxian great uncle has passed away and she has inherited a cool $1 million.  She idles the day away dreaming of what she is going to spend this money on.  When she goes to start spending it the next day she has to ‘Catch Up’.  She held $1,000,020 for 1 day at a 12% per year decay rate.  Her first transaction will have a $328 decay fee tacked onto it.  That $328 will go straight into my account because I’m the only one who has ever put cash into her account. Not a bad return on spending $20...and I get to keep the wine.

This is a far-fetched scenario, but it shows the power of betting right.

Scenario 2:  The Established Merchant.

Like the last scenario, I’m going to buy a bottle of wine for $20. But this time I’m buying it from a wine merchant who has been growing their operation for a while and is established in the business.  I get the same 20 pref points in the account, but in this scenario, the merchant has already had revenues of $3,000,000 over the course of her operation.  As a result, my $20 only makes up 0.00000666666 of the total 3,000,020 prefs.  If this merchant likes to keep $100,000 in their account to mitigate risk, my one day's worth of pref payments(at a 12% decay rate) would only be $0.0002.  What a tiny sum!  Over a year that is only $.073 cents.

From this scenario, we learn that one shouldn’t expect grand riches from this setup, but if one were to buy a bottle of wine a week for 20 years you’d end up with a stipend of $75 / year for your participation in the Wine Economy. (This is a rough calculation and doesn’t take into account reduction in percentage of the wine merchant's account).  This is not a great ROI, but don’t forget, you still have all that wine.

The moral of these two stories is that over a lifetime of spending money with accounts that range in return between these two scenarios one can build up a nice recurring pref payment that can act as a form of earned basic income.

In addition, we have some new levers on the economy that we can pull to try to accelerate the velocity of money, combat inflation, and increase redistribution of wealth while maintaining the market incentives of capitalism.

Statutory Theft

One principle must be put in place for this all to work properly and that is the principle of the inalienable right to pref ownership.  This means that you cannot sell your prefs anymore than you can sell yourself into slavery.  I propose the concept of statutory theft as a legal guiding principle of how handle scams and inappropriate attempts to confiscate the value of future pref payments.  This is a difficult thing to implement in code and will be an important reason that we will need to look at rule of law in relation to deploying the Catallax system.

You can read more and explore the economic model I’ve built showing how this system can lead to increases in GDP and reduction in poverty in one of my other articles:  http://catallax.info/news/2015/4/19/a-published-model-of-hypercapitalism

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

To Part 2:  Pass Through, Legacy, and Folding the Blockchain

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);

}