📜 ⬆️ ⬇️

rholang - programming language for distributed systems

RChain is a distributed computing blockchain platform. As ethereum, only much faster. In theory, it can be scaled to infinity, the first implementation in practice can handle up to 40 thousand transactions per second. Technical details - in the document about the architecture .



Contracts on the RChain platform are written in the rholang language, with which I would like to introduce the habr audience. You can try to write and execute programs in this language either by downloading and running the Rchain node through the docker, or by using the interpreter on the site .


Full tutorial


Rolang (or simply po ) is a process-oriented language. All calculations on it are performed using the transfer of messages between the " channels ". Channels stored many messages. Ro is a completely asynchronous language, so the order in which messages are sent to channels does not play any role. For example, you can read a message from a channel and then perform some operation on this message. However, you can not send a message and then do something after the message is received. At the very least, without registering in a separate way the expectation of a delivery confirmation message. It should be noted that in this tutorial we will use the terms name and channel as synonyms. AT rhothe algebra on which rholang is based uses the term name , but since we can send and receive data with their help, they are semantically similar to channels .


Contracts and data submission


1 contract @"HelloWorld"(return) = { 2 return!("Hello, World!") 3 } | 4 new myChannel in { 5 @"HelloWorld"!(*myChannel) 6 } 


Data acquisition


 1 contract @"HelloAgain"(_) = { 2 new chan in { 3 chan!("Hello again, world!") | 4 for (@text <- chan) { Nil } 5 } 6 } | @"HelloAgain"!(Nil) 


State change


  1 new MakeCell in { 2 // Makes a single cell in which you can store values 3 contract MakeCell(@init, get, set) = { 4 new valueStore in { 5 valueStore!(init) | 6 contract get(ack) = { 7 for(@value <- valueStore) { 8 valueStore!(value) | ack!(value) 9 } 10 } | 11 contract set(@newValue, ack) = { 12 for(_ <- valueStore) { 13 valueStore!(newValue) | ack!(true) 14 } 15 } 16 } 17 } | 18 // Cell usage. 19 new myGet, mySet in { 20 MakeCell!(123, *myGet, *mySet) | 21 new ack in { 22 myGet!(*ack) | 23 for (@result <- ack) { 24 //result now contains the value 123 25 mySet!(456, *ack) | 26 for (_ <- ack) { 27 myGet!(*ack) | 28 for (@result <- ack) { 29 //result now contains the value 456 30 Nil 31 } 32 } 33 } 34 } 35 } 36 } 

  1. We create a new MakeCell channel and then use it on line 3 as the name of the internal contract. No other process besides code in this lexical environment can invoke it.
  2. The MakeCell contract needs three arguments. The first argument is the value that this cell will contain. The second and third are the channels through which the cell will receive read and write requests. Note that the first argument should be a process, and the second and third should be names. Since the names are always sent through the channels, the first argument will be a pattern starting with @ , which indicates that the resulting name is a quoted process and we want to associate this process with a variable.
  3. To save the value, we create a new channel. This channel will contain at most one value, the current value of the cell.
  4. There are no messages on this valueStore channel before this line. After we set the initial value, this value will be the only one on this channel.
  5. We run a contract that listens on the reading channel. Every time a message is received, the body of the contract is executed.
  6. We are blocking a contract until you receive a message on the valueStore channel. Since the channel valueStore can expect no more than one message, reading the message is a kind of lock.
  7. We again transmit the current valueStore value channel, opening the processing of other messages and removing the block. Now we pass the current value back to the client on the ack channel.
  8. In sync with the get contract, we run a contract that listens to set.
  9. We block it until a message appears on the valueStore , and then we read it. We discard the message we read.
  10. We send a new value to the repository on the valueStore channel and give a signal that the operation has completed.


Note the depth of the layers to which the call applies. Ro is designed specifically to describe synchronous computations and therefore it is necessary to explicitly indicate the order of actions where in other languages ​​this goes without saying.


Conclusion


Ro is a language that is designed to be used on blockchains, but we have not yet reached the device of nodes, namespaces, wallets, Rev and phlogiston, network structure, or the Casper consensus algorithm.


Full tutorial .


')

Source: https://habr.com/ru/post/354398/


All Articles