(Re)building the Billion Dollar Ethereum World Computer from Scratch (Zero) in Ruby

Hello,

    a little weekend experiment - let's (re)build the billion dollar
ethereum world computer from scratch (zero) using a 25-year-old
contract language - ruby :slight_smile: - and ye good 40-year-old SQL databases.

    See a first live converted gold mine / token contract in universum
e.g. token.rb [1]

require 'universum'

class Token < Contract
  class Transfer < Event
      def initialize( from:, to:, value: )
        @from, @to, @value = from, to, value
     end
   end
   class Approval < Event
     def initialize( owner:, spender:, value: )
        @owner, @spender, @value = owner, spender, value
     end
   end

   def initialize( name:, symbol:, decimals:, initial_supply: )
     @name = name
     @symbol = symbol
     @decimals = decimals
     @total_supply = initial_supply * (10 ** decimals)
     @balances = Hash.new(0) ## note: special hash (default value is 0
and NOT nil)
    @balances[msg.sender] = @total_supply
    @allowed = {}
   end

   def balance_of( owner: )
      @balances[owner]
   end

   def transfer( to:, value: )
     if assert( @balances[msg.sender] >= value ) &&
        assert( @balances[to] + value >= @balances[to] )
       @balances[msg.sender] -= value # Subtract from the sender
       @balances[to] += value # Add the same to the recipient
       log Transfer.new( from: msg.sender, to: to, value: value )
       true
     else
       false
     end
  end

    ....

    Let's put ruby on ~~rails~~ the blockchain :-). And the proof-of-pudding.
Some test assertions in token_test.rb [2] thanks to minitest:

    class TestToken < Minitest::Test

      def setup
        @token = Token.new(
          name: 'Your Crypto Token',
          symbol: 'YOU',
          decimals: 8,
          initial_supply: 1_000_000
        )
      end

      def test_transfer
        assert_equal 100_000_000_000_000, @token.balance_of( owner: '0x0000' )
        assert_equal 0, @token.balance_of( owner: '0x1111' )

        assert @token.transfer( to: '0x1111', value: 100 )
        assert_equal 100, @token.balance_of( owner: '0x1111' )

        assert @token.transfer( to: '0x2222', value: 200 )
        assert_equal 200, @token.balance_of( owner: '0x2222' )

        assert_equal 99_999_999_999_700, @token.balance_of( owner: '0x0000' )
      end

      #...

    end

     Let's build the next world (blockchain) computer with Ruby :-).
Universum is the new Ethereum (2.0). Join in.

    Cheers. Prost.

[1] https://github.com/openblockchains/universe/blob/master/tokens/token.rb.
[2] https://github.com/openblockchains/universe/blob/master/tokens/token_test.rb

Hello,

  the little weekend experiment continuted - let's (re)build the
billion dollar ethereum world computer from scratch (zero)
using a 25-year-old contract language - ruby :slight_smile: - and ye good
40-year-old SQL databases. What's news?

Use the new ActiveContract machinery to store the contract (world)
state in the blockchain using - surprise, surprise - SQL database
storage.
See a first live converted gold mine / token contract in universum
with SQL storage e.g. token_sql.rb [1]:

     class TokenStorage

···

###############################
       # Variables of the token
       # name: public(bytes32)
       # symbol: public(bytes32)
       # totalSupply: public(uint256)
       # decimals: public(uint256)
       # balances: int128[address]
       # allowed: int128[address][address]

       def self.up
         ActiveRecord::Schema.define do
           create_table :token_storages do |t|
             t.string :addr, null: false
             t.string :name
             t.string :symbol
             t.integer :decimals
             t.integer :total_supply, :limit => 8
           end

          create_table :token_balances do |t|
             t.string :addr, null: false
             t.string :key, null: false
             t.integer :value, null: false, default: 0, :limit => 8
          end

          create_table :token_allowances do |t|
             t.string :addr, null: false
             t.string :key1, null: false
             t.string :key2, null: false
             t.integer :value, null: false, default: 0, :limit => 8
          end
         end # Schema.define
       end # method up
     end # class

     class Token < ActiveContract

       ############################
       # Events of the token
       class Transfer < Event
         def initialize( from:, to:, value: )
           @from, @to, @value = from, to, value
         end
       end

       class Approval < Event
         def initialize( owner:, spender:, value: )
           @owner, @spender, @value = owner, spender, value
         end
       end

       ####################################
       # Storage (a.k.a. SQL Database)

       class Balance < ActiveRecord::Base
          self.table_name = 'token_balances'
       end

       class Allowance < ActiveRecord::Base
          self.table_name = 'token_allowances'
       end

       # use "convenience" helpers for array-like (e.g. []) access to mappings
       BalanceMapping = Mapping.create( Balance, :key )
       AllowanceMapping = Mapping.create( Mapping.create( Allowance,
:key2 ), :key1 )

       class Storage < ActiveRecord::Base
          self.table_name = 'token_storages'

          def balances() BalanceMapping.new( addr: addr ); end
          def allowances() AllowanceMapping.new( addr: addr ); end
       end
       ...

Let's put ruby on the blockchain :-). Cheers. Prost.

[1] https://github.com/openblockchains/universe/blob/master/tokens/token_sql.rb

Gerald,

I am confused - is this proposed exercise serious or just an exercise?

Thanks,

Phil.

···

On 2018-05-05 23:03, Gerald Bauer wrote:

Hello,

  the little weekend experiment continuted - let's (re)build the
billion dollar ethereum world computer from scratch (zero)
using a 25-year-old contract language - ruby :slight_smile: - and ye good
40-year-old SQL databases. What's news?

Use the new ActiveContract machinery to store the contract (world)
state in the blockchain using - surprise, surprise - SQL database
storage.
See a first live converted gold mine / token contract in universum
with SQL storage e.g. token_sql.rb [1]:

     class TokenStorage
       ###############################
       # Variables of the token
       # name: public(bytes32)
       # symbol: public(bytes32)
       # totalSupply: public(uint256)
       # decimals: public(uint256)
       # balances: int128[address]
       # allowed: int128[address][address]

       def self.up
         ActiveRecord::Schema.define do
           create_table :token_storages do |t|
             t.string :addr, null: false
             t.string :name
             t.string :symbol
             t.integer :decimals
             t.integer :total_supply, :limit => 8
           end

          create_table :token_balances do |t|
             t.string :addr, null: false
             t.string :key, null: false
             t.integer :value, null: false, default: 0, :limit => 8
          end

          create_table :token_allowances do |t|
             t.string :addr, null: false
             t.string :key1, null: false
             t.string :key2, null: false
             t.integer :value, null: false, default: 0, :limit => 8
          end
         end # Schema.define
       end # method up
     end # class

     class Token < ActiveContract

       ############################
       # Events of the token
       class Transfer < Event
         def initialize( from:, to:, value: )
           @from, @to, @value = from, to, value
         end
       end

       class Approval < Event
         def initialize( owner:, spender:, value: )
           @owner, @spender, @value = owner, spender, value
         end
       end

       ####################################
       # Storage (a.k.a. SQL Database)

       class Balance < ActiveRecord::Base
          self.table_name = 'token_balances'
       end

       class Allowance < ActiveRecord::Base
          self.table_name = 'token_allowances'
       end

       # use "convenience" helpers for array-like (e.g. ) access to mappings
       BalanceMapping = Mapping.create( Balance, :key )
       AllowanceMapping = Mapping.create( Mapping.create( Allowance,
:key2 ), :key1 )

       class Storage < ActiveRecord::Base
          self.table_name = 'token_storages'

          def balances() BalanceMapping.new( addr: addr ); end
          def allowances() AllowanceMapping.new( addr: addr ); end
       end
       ...

Let's put ruby on the blockchain :-). Cheers. Prost.

[1] https://github.com/openblockchains/universe/blob/master/tokens/token_sql.rb

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--
Philip Rhoades

PO Box 896
Cowra NSW 2794
Australia
E-mail: phil@pricom.com.au

I am confused - is this proposed exercise serious or just an exercise?

Yes, it is a serious exercise :-). I'm all in :-), see the
/openblockchains [1] org on github for more goodies / gems / libs
(e.g. centralbank, ledger.lite, blockchain.lite, merkletree, ... ) in
ruby.

  The idea is to start with real-world (smart and not so smart)
contract samples from ethereum and
run them with plain vanilla standard ruby on the "universum" world
computer that stores the world state in SQL databases.

   The next step is adding / filling in some more missing building
blocks e.g. the peer-to-peer network / message exchange etc.

  The message is that with all the crypto-pseudo newspeak / talk -
it's all just code and data, really. No magic and you can use ruby
(even for building the latest and greatest world computer 2.0 from
scratch as a random nobody (no crypto god or ninja or wunderkind
needed) in a couple of weeks).

   You're welcome to join in. Universum version 0.1 is code-named Big Bang!

   Cheers. Prost.

PS: There's also an ActiveContract / Universum comment thread on reddit ruby [2]

[1] Blockchain! Blockchain! Blockchain! · GitHub
[2] Reddit - Dive into anything