Last active
August 4, 2021 09:41
-
-
Save jimscarver/17a376101e0bc3f270ad2ce99ae0c820 to your computer and use it in GitHub Desktop.
Rholang graph node contract (for graphql)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"} | |
*/ |
Author
jimscarver
commented
Dec 10, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment