Class , this, constructor, init --- for BitCoin and BlockChain

73 views
Skip to first unread message

Bert Mariani

unread,
Dec 11, 2017, 9:49:35 AM12/11/17
to The Ring Programming Language
Hello Mahmoud

I have been trying to convert this JavaScript to Ring, but getting confused.
It uses "Class", "this", "constructor", "const"


From the Ring docs ---  constructors are not used.
Not sure what to do about the "this"
Ring uses "init"  -- not sure when they are needed or not needed.

I was wondering if you can give me some help.


###=============================

const SHA256 = require("crypto-js/sha256");

###==============================

let savjeeCoin = new Blockchain();
savjeeCoin.addBlock(new Block(1, "20/07/2017", { amount: 4 }));
savjeeCoin.addBlock(new Block(2, "20/07/2017", { amount: 8 }));

###==============================

// Check if chain is valid (will return true)
console.log('Blockchain valid? ' + savjeeCoin.isChainValid());

// Let's now manipulate the data
savjeeCoin.chain[1].data = { amount: 100 };

// Check our chain again (will now return false)
console.log("Blockchain valid? " + savjeeCoin.isChainValid());

###==============================
###==============================

class Block {
    constructor(index, timestamp, data, previousHash = '') {
        this.index = index;
        this.previousHash = previousHash;
        this.timestamp = timestamp;
        this.data = data;
        this.hash = this.calculateHash();
    }

    calculateHash() {
        return SHA256(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data)).toString();
    }
}

###====================

class Blockchain{
    constructor() {
        this.chain = [this.createGenesisBlock()];
    }

    createGenesisBlock() {
        return new Block(0, "01/01/2017", "Genesis block", "0");
    }

    getLatestBlock() {
        return this.chain[this.chain.length - 1];
    }

    addBlock(newBlock) {
        newBlock.previousHash = this.getLatestBlock().hash;
        newBlock.hash = newBlock.calculateHash();
        this.chain.push(newBlock);
    }

    isChainValid() {
        for (let i = 1; i < this.chain.length; i++){
            const currentBlock = this.chain[i];
            const previousBlock = this.chain[i - 1];

            if (currentBlock.hash !== currentBlock.calculateHash()) {
                return false;
            }

            if (currentBlock.previousHash !== previousBlock.hash) {
                return false;
            }
        }
        return true;
    }
}

###============================

Mahmoud Fayed

unread,
Dec 11, 2017, 12:19:28 PM12/11/17
to ring...@googlegroups.com
Hello Bert

(1) In Ring, we don't use const
What you have is Variables that you can change at any time

If you have a constant, You can use C_ in the start of the name
For example C_MY_CONSTANT
But this will not have any change on the behavior of the program
You still can change it.

(2) In Ring we have 2 constructors

The first is what we have after the class name and before methods (Class Region)
We use this if we don't need getting parameters when creating the object

p1 = new point      # no () after class name (point)
class point
# here the class region
  x
= 10       # default value
  y
= 20       # default value
  x
= 30       # default value

The second constructor is the init() method that we can use when we create an object and pass parameters to it

p1 = new point(100,200,300)  # Now we pass parameters
class point
   x
=10  y=20  z=30
   func init nX
,nY,nZ
     x
=nX  y=nY  z=nZ

(3) In Ring we have self and this (In many cases they are optional - not required)

Self and This are the same thing, They point to the current object
But self, if used inside braces, will access the object that we are accessing using braces
But this, will still point to the object that we will create from the current class

class point
 
self.x = 10     # if x is global, Here using self.x avoid the global variable  
 
self.y = 20     # so using self is just a protection from global variables  
 
self.z = 30
  func draw
       
# some code to draw the point using RingAllegro, RingLibSDL or RingQt
       
# Another code (just for test)
          x      
= 100  # Try to use x, search in local variables then object attributes
         
self.x = 100  # Try to use x, search in attributes directly
         
this.x = 200  # In this location this.x is the same as self.x
       
# Special case
          oSomeObject
= new AnotherClass  # here we create object from another class
          oSomeObject
{                   # here we access the new object using braces
               
self.x = 100               # self.x = oSomeObject.x
               
this.x = 100               # this.x will access object from the Point class
                                         
# using this we escape from braces {}
                                         
# This is smart and know the current class
                                         
# But Self just access the active object
         
}
 

(4) More resources

http://ring-lang.sourceforge.net/doc1.6/oop.html

Greetings,
Mahmoud

Bert Mariani

unread,
Dec 13, 2017, 4:33:53 PM12/13/17
to The Ring Programming Language
Hello Mahmoud

I cannot seem to get this code to run using Classes
Can you take a look at the code and error messages when calling the Class with args provided.

==================
OUTPUT

sha256('hello') : 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
sha256('apple') : 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b

index: 0
timestamp: 2001/01/01
data: funcInit-GenesisCoin
previoushash: 1234
hash: d27f8d778e346bd51f0f81cf9326a8fa6faf701f237420f0f66698f54b6ea069

index: 1
timestamp: 01/12/2017
data: 4
previoushash: abcd
hash: dca1e6d90c7b171389a9c8d7d44f89cd837674dae1e4085d9974c28c0d12c333


Line 29 Error (R20) : Calling function with extra number of parameters!
In method init() in file C:/MyStuff/AA-BitCoin-1.ring
called from line 29  in file C:/MyStuff/AA-BitCoin-1.ring

==============================================
INPUT

# Load Ring Libraries
    Load "guilib.ring"
    Load "stdlib.ring"

see "sha256('hello') : " + sha256("hello") + nl 
see "sha256('apple') : " + sha256("apple") + nl +nl

### Block() uses func-init value when called with no args
 
    BertBlock = new Block()   ### Need the ()
    See BertBlock ; See nl
 
### Modify existing Block --- one piece at a time
    
    BertBlock.index        = "1"
    BertBlock.timestamp    = "01/12/2017"
    BertBlock.data         = "4"
    BertBlock.previousHash = "abcd"
    BertBlock.hash         = BertBlock.calculateHash()

    See BertBlock ; See nl
 
### Block() with args provided

### Line 27 Error (R20) : Calling function with extra number of parameters!,
### Line 27 Error (R24) : Using uninitialized variable : calculatehash
   
    BertBlock = new Block( index="2", timestamp="20/07/2017", data="Exodus" ) ### , previousHash="wxyz" , hash=calculateHash )

### Line (30) Error (C18) : Missing closing brace for the block opened!
   
   # BertBlock = new Block{ index="2", timestamp="20/07/2017", data="Exodus", previousHash="wxyz" }
   # See BertBlock ; See nl



#BertChain = new Blockchain();
#BertChain.addBlock(new Block(1, "20/07/2017", "Amount-4") );
#BertChain.addBlock(new Block(2, "20/07/2017", "Amount-8"));


###===========================

class Block 
{
    index="1" timestamp="2" data="3" previousHash="4" hash="5"
   
    func init() 
    {
      this.index        = "0"
      this.timestamp    = "2001/01/01" 
      this.data         = "funcInit-GenesisCoin" 
      this.previousHash = "1234"
      this.hash         = calculateHash()
    }
    func calculateHash() 
    {
      return SHA256( this.index + this.previousHash + this.timestamp + this.data );
    }
}

###============================

class Blockchain
{
    chain 
    func init()
    {
        this.chain = [this.createGenesisBlock()];
    }

    func createGenesisBlock() 
    {
        return new Block(0, "01/01/2017", "Genesis block", "0");
    }

    func getLatestBlock() 
    {
        return this.chain[this.chain.length - 1];
    }

    func addBlock(newBlock) 
    {
        newBlock.previousHash = this.getLatestBlock().hash;
        newBlock.hash         = newBlock.calculateHash();
        this.chain.push(newBlock);
    }


}

###======================================



AA-BitCoin-1.ring

Mahmoud Fayed

unread,
Dec 13, 2017, 6:22:23 PM12/13/17
to The Ring Programming Language
Hello Bert

Change this line

BertBlock = new Block( index="2", timestamp="20/07/2017", data="Exodus" )

To
BertBlock = new Block() { index="2" timestamp="20/07/2017" data="Exodus" }

And modify the init() method in the Block class
change

    func init()

    {  


      this.index        = "0"


      this.timestamp    = "2001/01/01"


      this.data         = "funcInit-GenesisCoin"


      this.previousHash = "1234"


      this.hash         = calculateHash()



    }


To (use return self)
    func init()

    {  


      this.index        = "0"


      this.timestamp    = "2001/01/01"


      this.data         = "funcInit-GenesisCoin"


      this.previousHash = "1234"


      this.hash         = calculateHash()


      return self


    }


Greetings,
Mahmoud

Bert Mariani

unread,
Dec 15, 2017, 2:52:46 PM12/15/17
to The Ring Programming Language
Hello Mahmoud

Thanks for your suggested fixes.

I still have not been able to convert Savjee's  JavaScript what uses OOPs and Classes to Ring.
Ring seems more complicated in how it passes  args using  ()  and {}  etc
Can you give it a try to translate the JavaScript.


Example

   #BlockChainBlk = new Block() {"3" "01/01/2017" "Blockchain block"}   ###  Needs {} , Does not like position data
   #BlockChainBlk = new Block() {index="3", timestamp="01/01/2017", data="Blockchain block"}   ###  Does not like commas between args
   
     BlockChainBlk = new Block() {index="3" timestamp="01/01/2017" data="Blockchain block"}   ###  more complicated than JavaScripts  which accepts the args in ()
    See "BlockChainBlk"+nl  See BlockChainBlk  See nl


   return this.chain = [ this.createGenesisBlock() ]  ###  Line 70 Error (R21) : Using operator with values of incorrect type

   return this.chain[this.chain.length - 1];  ###   Class args does not have a dot.length

On Monday, December 11, 2017 at 9:49:35 AM UTC-5, Bert Mariani wrote:
AA-BitCoin-1.ring
AA-BitCoin=Savjee.ring
AA-BitCoin=Savjee-2.ring

Mahmoud Fayed

unread,
Dec 15, 2017, 7:26:54 PM12/15/17
to The Ring Programming Language
Hello Bert


Ring seems more complicated in how it passes  args using  ()  and {}  etc

This is not correct!
It's not Ring, It's the code itself!

You can pass arguments using () directly
Just redefine your init() method to accept these parameters

func init p1,p2,p3
   
#here we can use p1,p2,p3

When you create the object
new myclass(p1Value,p2Value,p3Value)

Greetings,
Mahmoud

Bert Mariani

unread,
Dec 16, 2017, 9:11:04 AM12/16/17
to The Ring Programming Language
Hello Mahmoud

These are the variations that are causing errors:
Attached  AA-BitCoin-1b.ring

==================================

##---------------------------- 
### Block() with args provides.
   
    BertBlock = new Block("2", "20/07/2017", "Exodus" )   ### <<< Line 24 Error (R20) : Calling function with extra number of parameters!
    See "1-BertBlock() with args and commas"+ nl See BertBlock ; See nl
### Block() with args provides. No comma separators
   
    BertBlock = new Block("2" "20/07/2017" "Exodus" )   ### <<< Line (29) Error (C8) : Parentheses ')' is missing
    See "2-BertBlock() with args no commas"+ nl See BertBlock ; See nl

### Block() with args provides. No comma separators
   
    BertBlock = new Block(index="2" timestamp="20/07/2017" data="Exodus" ) ### <<< Line (34) Error (C8) : Parentheses ')' is missing
    See "3-BertBlock() with args=value"+ nl See BertBlock ; See nl
### Block(){} with args provides. No comma separators
   
    BertBlock = new Block() { index="2", timestamp="20/07/2017", data="Exodus" }  ### <<<  Line (39) Error (C18) : Missing closing brace for the block opened!
    See "4-BertBlock(){} with args and commas"+ nl See BertBlock ; See nl
### Block(){} with args provides. No comma separators
   
    BertBlock = new Block() { index="2" timestamp="20/07/2017" data="Exodus" }  ###<<< No complains on this format
    See "5-BertBlock(){} with args=value no commas"+ nl See BertBlock ; See nl
###----------------------

class Blockchain
{
    chain = []
    func init()
    {   
        return this.chain = [ this.createGenesisBlock() ]  ### <<< Line 89 Error (R21) : Using operator with values of incorrect type
    }

###----------------------


C:/MyStuff/AA-BitCoin-1b.ring Line (29) Error (C8) : Parentheses ')' is missing
C:/MyStuff/AA-BitCoin-1b.ring Line (34) Error (C8) : Parentheses ')' is missing
C:/MyStuff/AA-BitCoin-1b.ring Line (39) Error (C18) : Missing closing brace for the block opened!
C:/MyStuff/AA-BitCoin-1b.ring errors count : 3

C:/MyStuff/AA-BitCoin-1b.ring Line (34) Error (C8) : Parentheses ')' is missing
C:/MyStuff/AA-BitCoin-1b.ring Line (39) Error (C18) : Missing closing brace for the block opened!
C:/MyStuff/AA-BitCoin-1b.ring errors count : 2

C:/MyStuff/AA-BitCoin-1b.ring Line (39) Error (C18) : Missing closing brace for the block opened!
C:/MyStuff/AA-BitCoin-1b.ring errors count : 1

Line 24 Error (R20) : Calling function with extra number of parameters!
In method init() in file C:/MyStuff/AA-BitCoin-1b.ring
called from line 24  in file C:/MyStuff/AA-BitCoin-1b.ring

Line 89 Error (R21) : Using operator with values of incorrect type
In method init() in file C:/MyStuff/AA-BitCoin-1b.ring
called from line 50  in file C:/MyStuff/AA-BitCoin-1b.ring

====================================



On Monday, December 11, 2017 at 9:49:35 AM UTC-5, Bert Mariani wrote:
AA-BitCoin-1b.ring

Mahmoud Fayed

unread,
Dec 16, 2017, 3:54:13 PM12/16/17
to ring...@googlegroups.com
Hello Bert

When you write a class, You determine how it will be used.

(1) In this code


### Block() with args provides.
BertBlock = new Block("2", "20/07/2017", "Exodus" )  
### <<< Line 24 Error (R20) : Calling function with extra number of parameters!

Your code assume that the Block class contains init() method that takes 3 parameters
But in your class code, This is not true!
Where the init() method doesn't take any parameters
 func init()

So You have 2 options
* Modifiy the init() method
* Modify your code when using it

(2) In this code


### Block() with args provides. No comma separators
BertBlock = new Block("2" "20/07/2017" "Exodus" )  
### <<< Line (29) Error (C8) : Parentheses ')' is missing

The error is clear, You must separate between parameters using comma
Like any function/method call in Ring, We separate between parameters using comma!

(3) In this code


### Block(){} with args provides. No comma separators
BertBlock = new Block() { index="2", timestamp="20/07/2017", data="Exodus" }  
### <<<  Line (39) Error (C18) : Missing closing brace for the block opened!

The error is clear, You are adding comma that we don't need!
When we access an object using braces { }
We can interact directly with the object attributes (read/modify) using normal Ring code (Statements)

You must change this to

BertBlock = new Block() { index="2" timestamp="20/07/2017" data="Exodus" }

(4) Final Comments

You are using Ring, Not JavaScript!

* Follow the Ring way (Syntax) when writing the code
* Using braces { } to access objects is a special and powerful feature in Ring
* Using init() and passing parameters is like any function/method definition and call.

Greetings,
Mahmoud

Bert Mariani

unread,
Dec 16, 2017, 6:08:09 PM12/16/17
to The Ring Programming Language
Sorry Mahmoud

Its obvious that I do not understand how to write the Function with or without args or commas,  that call a Class, or how to code the Class in Ring.
I end up trying guesses  to figure it out what works and what doesn't.
I have not been successful

I read the Ring docs and looked at the "Point" example, but still do not understand enough
I do not understand the Ring Syntax rules.

It seems that I spend a more time fighting with the Syntax, than with the logic.. 
Example
  ABlock = new Block() { index="2"  timestamp="20/07/2017"  data="Exodus" }   <<< This Works with spaces
  BBlock = new Block() { index="2", timestamp="20/07/2017", data="Exodus" }   <<< This Fails with commas

I give up !


On Monday, December 11, 2017 at 9:49:35 AM UTC-5, Bert Mariani wrote:

Mahmoud Fayed

unread,
Dec 16, 2017, 9:10:02 PM12/16/17
to The Ring Programming Language
Hello Bert

Today, I will record a movie for you in English Language to explain these things :D

Greetings,
Mahmoud

Mahmoud Fayed

unread,
Dec 16, 2017, 11:32:04 PM12/16/17
to The Ring Programming Language
Hello Bert

I have already recorded this movie (In English Language) to explain Ring Classes and answer your question

https://www.youtube.com/watch?v=A6roiRtcXbQ&feature=youtu.be

Also attached

(1) The example in the Video
(2) Your example in this topic after doing some updates

Greetings,
Mahmoud


On Sunday, December 17, 2017 at 2:08:09 AM UTC+3, Bert Mariani wrote:
AA-BitCoin-1b.ring
test.ring

Bert Mariani

unread,
Dec 17, 2017, 4:43:50 PM12/17/17
to The Ring Programming Language
Thank you very much Mahmoud  
For the most excellent video explaining Classes, variables, functions, when to use comma, how to use init(), bracket and brace .... etc
And for the sample code.

Attached in my updated script for BitCoin-BlockChain
   - AA-BitCoin-2.ring

Note how the Blocks in the Chain are linked with the previous and current hash.

=========================
OUTPUT

Create an initial Block

index: 00
timestamp: 01/01/2001
data: Init-GenesisCoin
previoushash: 00
hash: fd8fe43647da2ae9ca74fba88bc387053a129cadf0a2a83a859c5b8b939c330b

-----------------
Create a BlockChain starting with a Genesis Coin
Display the Chain

index: 0
timestamp: 01/01/2017
data: GenesisCoin
previoushash: 0
hash: fd8fe43647da2ae9ca74fba88bc387053a129cadf0a2a83a859c5b8b939c330b

index: 1
timestamp: 21/11/2017
data: Amount-4
previoushash: fd8fe43647da2ae9ca74fba88bc387053a129cadf0a2a83a859c5b8b939c330b
hash: 724e4a2f1555d5a8443540c921287a434f3a7410becbc15158e25060667ffe04

index: 2
timestamp: 22/1/2017
data: Amount-8
previoushash: 724e4a2f1555d5a8443540c921287a434f3a7410becbc15158e25060667ffe04
hash: def39bf63bc63558bccd21f994688800a73ffd902252b360c0570a906f275e59

index: 3
timestamp: 23/11/2017
data: Amount-6
previoushash: def39bf63bc63558bccd21f994688800a73ffd902252b360c0570a906f275e59
hash: 6e74c90103f391e4980db9cafe81e7f81c1163e65d6285217d32dcccccafba28

------------------------
Display individual link in the Chain

index: 2
timestamp: 22/1/2017
data: Amount-8
previoushash: 724e4a2f1555d5a8443540c921287a434f3a7410becbc15158e25060667ffe04
hash: def39bf63bc63558bccd21f994688800a73ffd902252b360c0570a906f275e59





On Monday, December 11, 2017 at 9:49:35 AM UTC-5, Bert Mariani wrote:
AA-BitCoin-2.ring

Mahmoud Fayed

unread,
Dec 17, 2017, 6:19:36 PM12/17/17
to The Ring Programming Language
Hello Bert

Thanks for your kind words, You are welcome :D

It will be nice to add the sample to GitHub
https://github.com/ring-lang/ring/tree/master/samples/other

Keep up the good work :D

Greetings,
Mahmoud

Bert Mariani

unread,
Dec 18, 2017, 8:46:51 PM12/18/17
to The Ring Programming Language
Hello Mahmoud

Uploaded to GitHub and created the Pull Request  

BitCoin-BlockChain.ring

How to use Class, Variables, and Functions in an OOP's manner


Attached is the latest complete version of the program

it also checked if the BlockChain is Valid or if it has been tampered with


==================

OUTPUT



================= TEST if VALID CHAIN ===================


Len-BertChain.chain 4


Test isChainValid: VALID


Before Change: Block.data

index: 2

timestamp: 22/1/2017

data: Amount-8

previoushash: 0097e3096ad5638d419013a8f97168ea17838bc2cc723628445713deb7cc345b

hash: 00d482d5c02b468c5a966dfcf3cacebca98613f4a280936257d16e93f4fddbcc

nonce: 425.000000


After Change: Block.data

index: 2

timestamp: 22/1/2017

data: Amount-100

previoushash: 0097e3096ad5638d419013a8f97168ea17838bc2cc723628445713deb7cc345b

hash: 00d482d5c02b468c5a966dfcf3cacebca98613f4a280936257d16e93f4fddbcc

nonce: 425.000000


Test isChainValid: INVALID


===============================



On Monday, December 11, 2017 at 9:49:35 AM UTC-5, Bert Mariani wrote:
BitCoin-BlockChain.ring

Mahmoud Fayed

unread,
Dec 18, 2017, 9:05:32 PM12/18/17
to The Ring Programming Language
Hello Bert

Thanks for the update

Keep up the good work :D

Greetings,
Mahmoud

Reply all
Reply to author
Forward
0 new messages