Skip to content

Instantly share code, notes, and snippets.

@jimscarver
Last active August 4, 2021 09:41
Show Gist options
  • Save jimscarver/17a376101e0bc3f270ad2ce99ae0c820 to your computer and use it in GitHub Desktop.
Save jimscarver/17a376101e0bc3f270ad2ce99ae0c820 to your computer and use it in GitHub Desktop.
Rholang graph node contract (for graphql)
new Node, ret1, ret2, ret3, ret4, ret5, stdout(`rho:io:stdout`) in {
// Rholang Abstract Graph Node Object having properties and links, a contract, super, and public key
// Nodes can be used for hierarchical directories with loops suitable for use with graphql
// node data is a map of maps
// TODO encryption, inheritance, typing
contract Node(@"new", // class method to create a new node
@super, // node to query for links not found in current nde
@propsMap, // property map of node attributes
@linkMap, // map of named links from node
@pubKey, // TODO encryption TBD
return) = // return the address (name/channel) of the new node
{
stdout!(["new",{"super": super, "props": propsMap, "links": linkMap, "pubKey": pubKey }]) |
// include the contract address allowing flexibity and evolution of node behaviour
return!({"contract": *Node, "super": super, "props": propsMap, "links": linkMap, "pubKey": pubKey })
} |
// add a named link to this node
contract Node(this, @"linkAs", @name, @node2, ack) =
{
//stdout!("in linkAs") |
for (@nod <- this) {
//stdout!("got this") |
this!(nod.set("links",nod.get("links").set(name, node2))) |
ack!(Nil)
}
}|
// remove a named link from this node
contract Node(this, @"unLink", @name, ack) =
{
//stdout!("in unLink") |
for (@nod <- this) {
//stdout!("got this") |
this!(nod.set("links",nod.get("links").set(name, Nil))) |
ack!(Nil)
}
}|
// get a property value from this node
contract Node(this, @"get", @name, value) = {
for (@nod <- this) {
this!(nod) |
value!(nod.get("props").get(name))
}
}
// set a property value of this node
| contract Node(this, @"set", @name, @value, ack) = {
for (@nod <- this) {
//stdout!("got this") |
this!(nod.set("props",nod.get("props").set(name,value))) |
ack!(Nil)
}
}
// query down a sequence of linked nodes from this node
| contract Node(this, @"query", @nameList, return) = {
//stdout!(["in query", nameList, *this]) |
for (@nod <- this) {
this!(nod) |
match(nameList)
{ [last] => {
//stdout!(["match last",last, "in", nod]) |
if (last == "self") { // "self" is a virtual ref to the node itself
return!(*this)
} else {
if ( nod.get(last) == Nil ) {
// TODO ask super?
stdout!(["last",last,"not found in",nod])
} else {
return!(nod.get(last))
}
}
}
[head,...tail] => {
//stdout!(["match head",head, nod.get("links").get(head),tail, nod]) |
if ( nod.get("links").get(head) != Nil ) {
// head is the name of a node in the links map
//stdout!("calling Node",nod.get("links").get(head), "query", tail, *return) |
// query the remaining link names from the found link name
@{nod.get("contract")}!(nod.get("links").get(head), "query", tail, *return)
} else {
stdout!(["head",head,"is not the name of a node in the link map of",nod]) |
// ask super?
if (nod.get("super") != Nil ) {
@{nod.get("contract")}!(nod.get("super"),"query",nameList,*return)
} else {
return!(Nil)
}
}
}
_ => {
stdout!("no match") |
return!(Nil)
}
}
}
}
// get the uri of the Node contract from the registry
| contract Node(@"register", ret) = {
new nodeChan, uriChan, insertArbitrary(`rho:registry:insertArbitrary`) in {
insertArbitrary!(bundle+{*Node}, *nodeChan) |
for(@uri <- nodeChan) {
stdout!(["contract", uri]) |
ret!(uri)
}
}
}
// get the uri of this node from the registry
| contract Node(this, @"register", ret) = {
new nodeChan, uriChan, insertArbitrary(`rho:registry:insertArbitrary`) in {
for( @node <- this) {
if (node.get("uri") != Nil ) {
ret!(node.get("uri")) |
this!(node)
} else {
insertArbitrary!(*this, *uriChan) |
for(@uri <- uriChan) {
stdout!(["node",uri]) |
this!(node.set("uri",uri)) |
ret!(uri)
}
}
}
}
}
| Node!("new",Nil,{"name": "root", "data": true},{},Nil,*ret1)
| Node!("new",Nil,{"name": "contracts"},{},Nil,*ret2)
| Node!("new",Nil,{"name": "a 3rd node"},{"loop": *ret1},Nil,*ret3)
| Node!(*ret1,"linkAs","next", *ret2, *ret4)
| Node!(*ret2,"linkAs","end", *ret3, *ret5)
| Node!(*ret2,"linkAs","Node", *Node, *stdout)
| for ( nod1 <- ret1; nod2 <- ret2; nod3 <- ret3; _ <- ret4; _ <- ret5 ) {
//stdout!("got the nodes back") |
ret1!(*nod1)
| ret2!(*nod2)
| ret3!(*nod3)
| Node!(*ret1,"query", ["next", "end", "loop", "next", "props"], *stdout) // {"name": "contracts"}`
| Node!(*ret1, "register", *stdout)
| stdout!(*nod3)
| stdout!(*nod2)
| stdout!(*nod1)
}
}
/* output
![resulting graph](https://cdn.discordapp.com/attachments/481106525734305792/521442480659628044/Node.png)
["new", {"links" : {}, "props" : {"data" : true, "name" : "root"}, "pubKey" : Nil, "super" : Nil}]
["new", {"links" : {}, "props" : {"name" : "contracts"}, "pubKey" : Nil, "super" : Nil}]
["new", {"links" : {"loop" : Unforgeable(0xf6991a949f56bc6c1fb107e156a9d3b6e69a0be528fb749867fffa3f013aba94)}, "props" : {"name" : "a 3rd node"}, "pubKey" : Nil, "super" : Nil}]
Nil
{"contract" : Unforgeable(0xa8511dfc749403d47420db971fd1bdb3f2cc7650682deed5a9e9a3d8bcebdd36), "links" : {"Node" : Unforgeable(0xa8511dfc749403d47420db971fd1bdb3f2cc7650682deed5a9e9a3d8bcebdd36), "end" : Unforgeable(0x13edde2b4159717f795dc08fcef08c8507c93db101415afb917773a969480a3e)}, "props" : {"name" : "contracts"}, "pubKey" : Nil, "super" : Nil}
{"contract" : Unforgeable(0xa8511dfc749403d47420db971fd1bdb3f2cc7650682deed5a9e9a3d8bcebdd36), "links" : {"next" : Unforgeable(0x1263a571bef1f715cd30b12fb47a19792dc428eb52b09a56e6e47435ca1041a0)}, "props" : {"data" : true, "name" : "root"}, "pubKey" : Nil, "super" : Nil}
{"contract" : Unforgeable(0xa8511dfc749403d47420db971fd1bdb3f2cc7650682deed5a9e9a3d8bcebdd36), "links" : {"loop" : Unforgeable(0xf6991a949f56bc6c1fb107e156a9d3b6e69a0be528fb749867fffa3f013aba94)}, "props" : {"name" : "a 3rd node"}, "pubKey" : Nil, "super" : Nil}
`rho:id:ozb3hxu7nwgnx64m6fn68nzhczahsuonrrzx99kmnhazcr8hbkmwfa`
["node", `rho:id:ozb3hxu7nwgnx64m6fn68nzhczahsuonrrzx99kmnhazcr8hbkmwfa`]
{"name" : "contracts"}
*/
@jimscarver
Copy link
Author

resulting graph

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment