{"id":20614578,"url":"https://github.com/rayniel95/rainyelcert-node","last_synced_at":"2026-02-26T06:38:04.776Z","repository":{"id":115369545,"uuid":"376069019","full_name":"rayniel95/rainyelcert-node","owner":"rayniel95","description":"The node of RainyelLedger, permissioned blockchain created using Substrate. RainyelLedger is a rebranding of RainyelCert-Node :)","archived":false,"fork":false,"pushed_at":"2021-11-30T18:24:48.000Z","size":900,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-31T07:49:03.004Z","etag":null,"topics":["blockchain","cryptography","distributed-systems","ink","permissioned-blockchain","polkadot","rust","smart-contracts","substrate"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rayniel95.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-11T15:32:17.000Z","updated_at":"2024-09-28T02:05:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"37d56d29-e223-45a3-99a6-c286c24aafbe","html_url":"https://github.com/rayniel95/rainyelcert-node","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"polkadot-developers/substrate-node-template","purl":"pkg:github/rayniel95/rainyelcert-node","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayniel95%2Frainyelcert-node","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayniel95%2Frainyelcert-node/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayniel95%2Frainyelcert-node/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayniel95%2Frainyelcert-node/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rayniel95","download_url":"https://codeload.github.com/rayniel95/rainyelcert-node/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayniel95%2Frainyelcert-node/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29850321,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-25T22:37:40.667Z","status":"online","status_checked_at":"2026-02-26T02:00:06.774Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","cryptography","distributed-systems","ink","permissioned-blockchain","polkadot","rust","smart-contracts","substrate"],"created_at":"2024-11-16T11:13:05.481Z","updated_at":"2026-02-26T06:38:04.758Z","avatar_url":"https://github.com/rayniel95.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# About\n\nRainyelLedger is a permissioned blockchain platform that is capable of execute smart \ncontracts programmed with ink!. The request to the contract storage is made via RPC and authorization of administrators is necessary to join the network. Instantiation of the smart contracts on the network is only authorized to administrators. The node of Substrate was modified to create a permissioned node, the authorization node pallet was used to provide access to the network, the smart contract pallet was modified to provide feeless smart contract execution. RainyelLedger was created using [Substrate][1].\n\n# Requirements\n\n- cargo-chef v0.1.21\n- Docker\n\n# How to execute\n\nExecute \n\n```sh \ndocker build -f Dockerfile-debug -t rayniel95/rainyelledger:v0.1 ./\n``` \n\nto create the docker image.\n\nExecute \n\n```sh \ndocker run --rm -it --network host rayniel95/rainyelledger:v0.1 ./node-template --tmp --dev\n``` \n\nto run the node.\n\n# Creating a test network\n\nFor this demonstration, we'll launch 4 nodes: 3 well known nodes that are allowed to author and validate blocks, and 1 sub-node that only has read-only access to data from a selected well-known node (upon it's approval).\n\n## Obtaining Node Keys and PeerIDs\n\n### For Alice's well known node:\n\n```bash\n# node key\nc12b6d18942f5ee8528c8e2baf4e147b5c5c18710926ea492d09cbd9f6c9f82a\n\n# peerid, generated from node key\n12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2\n\n# bs58 decoded peer id in hex:\n0024080112201ce5f00ef6e89374afb625f1ae4c1546d31234e87e3c3f51a62b91dd6bfa57df\n```\n\n### For Bob's well known node:\n\n```bash\n# node key\n6ce3be907dbcabf20a9a5a60a712b4256a54196000a8ed4050d352bc113f8c58\n\n# peer id, generated from node key\n12D3KooWQYV9dGMFoRzNStwpXztXaBUjtPqi6aU76ZgUriHhKust\n\n# bs58 decoded peer id in hex:\n002408011220dacde7714d8551f674b8bb4b54239383c76a2b286fa436e93b2b7eb226bf4de7\n```\n\n### For Charlie's NOT well known node:\n\n```bash\n# node key\n3a9d5b35b9fb4c42aafadeca046f6bf56107bd2579687f069b42646684b94d9e\n\n# peer id, generated from node key\n12D3KooWJvyP3VJYymTqG7eH4PM5rN4T2agk5cdNCfNymAqwqcvZ\n\n# bs58 decoded peer id in hex:\n002408011220876a7b4984f98006dc8d666e28b60de307309835d775e7755cc770328cdacf2e\n```\n\n### For Dave's sub-node (to Charlie, more below):\n\n```bash\n# node key\na99331ff4f0e0a0434a6263da0a5823ea3afcfffe590c9f3014e6cf620f2b19a\n\n# peer id, generated from node key\n12D3KooWPHWFrfaJzxPnqnAYAoRUyAHHKqACmEycGTVmeVhQYuZN\n\n# bs58 decoded peer id in hex:\n002408011220c81bc1d7057a1511eb9496f056f6f53cdfe0e14c8bd5ffca47c70a8d76c1326d\n```\n\nThe nodes of Alice and Bob are already configured in genesis storage and serve as well known nodes. We will later add Charlie's node into the set of well known nodes. Finally we will add the connection between Charlie's node and Dave's node without making Dave's node as a well known node.\n\n## Alice and Bob Start the Network\n\nLet's start Alice's node first:\n\n```bash\ndocker run --rm -it --network host rayniel95/rainyelledger:v0.1 ./node-template \\\n--chain=local \\\n--base-path /tmp/validator1 \\\n--alice \\\n--node-key=c12b6d18942f5ee8528c8e2baf4e147b5c5c18710926ea492d09cbd9f6c9f82a \\\n--port 30333 \\\n--ws-port 9944\n```\n\nHere we are using --node-key to specify the key that are used for the security connection of the network. This key is also used internally to generate the human readable PeerId as shown in above section.\n\nOther used CLI flags are:\n\n- `--chain=local` for a local testnet (not the same as the `--dev` flag!).\n- `--alice` to make the node an authority which can author and finalize block, also give the node a name which is alice.\n- `--port` assign a port for peer to peer connection.\n- `--ws-port` assign a listening port for WebSocket connection.\n\nStart Bob's node:\n\n```bash\n# In a new terminal, leave Alice running\ndocker run --rm -it --network host rayniel95/rainyelledger:v0.1 ./node-template \\\n--chain=local \\\n--base-path /tmp/validator2 \\\n--bob \\\n--node-key=6ce3be907dbcabf20a9a5a60a712b4256a54196000a8ed4050d352bc113f8c58 \\\n--port 30334 \\\n--ws-port 9945\n```\n\nAfter both nodes are started, you should be able to see new blocks authored and finalized in bother terminal logs. Now let's use the [polkadot.js][2] apps and check the well known nodes of our blockchain. Don't forget to switch to one of our local nodes running: 127.0.0.1:9944 or 127.0.0.1:9945.\n\nFirstly, we need to add an extra setting to tell the frontend the type of the PeerId used in node-authorization pallet. Note: the format of PeerId here is a wrapper on bs58 decoded peer id in bytes. Go to the Settings Developer page in apps , add following custom type mapping information:\n\n```bash\n// add this as is, or with other required types you have set already:\n{\n  \"PeerId\": \"(Vec\u003cu8\u003e)\"\n}\n```\n\nThen, let's go to Developer page, Chain State sub-tab, and check the data stored in the nodeAuthorization pallet, wellKnownNodes storage. You should be able to see the peer ids of Alice and Bob's nodes, prefixed with 0x to show its bytes in hex format.\n\nWe can also check the owner of one node by querying the storage owners with the peer id of the node as input, you should get the account address of the owner.\n\n![](./img/get_well_known_nodes.png)\n\n## Add Another Well Known Node\n\nLet's start Charlie's node,\n\n```bash\ndocker run --rm -it --network host rayniel95/rainyelledger:v0.1 ./node-template \\\n--chain=local \\\n--base-path /tmp/validator3 \\\n--name charlie  \\\n--node-key=3a9d5b35b9fb4c42aafadeca046f6bf56107bd2579687f069b42646684b94d9e \\\n--port 30335 \\\n--ws-port=9946 \\\n--offchain-worker always\n```\n\nAfter it was started, you should see there are no connected peers for this node. This is because we are trying to connect to a permissioned network, you need to get authorization to to be connectable! Alice and Bob were configured already in the genesis chain_spec.rs, where all others mut be added manually via extrinsic.\n\nRemember that we are using sudo pallet for our governance, we can make a sudo call on add_well_known_node dispatch call provided by node-authorization pallet to add our node. You can find more avaliable calls in this reference doc.\n\nGo to Developer page, Sudo tab, in apps and submit the nodeAuthorization - add_well_known_node call with the peer id in hex of Charlie's node and the owner is Charlie, of course. Note Allice is the valid sudo origin for this call.\n\n![](./img/add_well_known_node.png)\n\nAfter the transaction is included in the block, you should see Charlie's node is connected to Alice and Bob's nodes, and starts to sync blocks. Notice the reason the three nodes can find each other is mDNS discovery mechanism is enabled by default in a local network.\n\nNow we have 3 well known nodes all validating blocks together!\n\n## Add Dave as a Sub-Node to Charlie\n\nLet's add Dave's node, not as a well-known node, but a \"sub-node\" of Charlie. Dave will only be able to connect to Charlie to access the network. This is a security feature: as Charlie is therefor solely responsible for any connected sub-node peer. There is one point of access control for David in case they need to be removed or audited.\n\nStart Dave's node with following command:\n\n```bash\ndocker run --rm -it --network host rayniel95/rainyelledger:v0.1 ./node-template \\\n--chain=local \\\n--base-path /tmp/validator4 \\\n--name dave \\\n--node-key=a99331ff4f0e0a0434a6263da0a5823ea3afcfffe590c9f3014e6cf620f2b19a \\\n--port 30336 \\\n--ws-port 9947 \\\n--offchain-worker always\n```\n\nAfter it was started, there is no available connections. This is a permissioned network, so first, Charlie needs to configure his node to allow the connection from Dave's node.\n\nIn the Developer Extrinsics page, get Charlie to submit an addConnections extrinsic. The first PeerId is the peer id in hex of Charlie's node. The connections is a list of allowed peer ids for Charlie's node, here we only add Dave's.\n\n![](./img/charlie_add_connections.png)\n\nThen, Dave needs to configure his node to allow the connection from Charlie's node. But before he adds this, Dave needs to claim his node, hopefully it's not too late!\n\n![](./img/dave_claim_node.png)\n\nSimilarly, Dave can add connection from Charlie's node.\n\n![](./img/dave_add_connections.png)\n\nYou should now see Dave is catching up blocks and only has one peer which belongs to Charlie! Restart Dave's node in case it's not connecting with Charlie right away.\n\n# Installing and playing with the smart contracts\n\nExecute the node:\n\n```bash\ndocker run --rm -it --network host rayniel95/rainyelledger:v0.1 ./node-template --dev --tmp\n```\n\nTo instantiate a smart contract, the extrinsic should be sumbited by the sudo account. It is not necessary to provide a gas limit because the extrinsics of the contract are feeless.\n\n![](./img/instantiate_contract.png)\n\nOnce the contract have been instantiated you can start submitting calls to it. It is possible to do RPC calls to the contract storage.\n\n### Embedded Docs\n\nOnce the project has been built, the following command can be used to explore all parameters and\nsubcommands:\n\n```sh\ndocker run --rm -it --network host rayniel95/rainyelledger:v0.1 ./node-template -h\n```\n\n## Template Structure\n\nA Substrate project such as this consists of a number of components that are spread across a few\ndirectories.\n\n### Node\n\nA blockchain node is an application that allows users to participate in a blockchain network.\nSubstrate-based blockchain nodes expose a number of capabilities:\n\n-   Networking: Substrate nodes use the [`libp2p`](https://libp2p.io/) networking stack to allow the\n    nodes in the network to communicate with one another.\n-   Consensus: Blockchains must have a way to come to\n    [consensus](https://substrate.dev/docs/en/knowledgebase/advanced/consensus) on the state of the\n    network. Substrate makes it possible to supply custom consensus engines and also ships with\n    several consensus mechanisms that have been built on top of\n    [Web3 Foundation research](https://research.web3.foundation/en/latest/polkadot/NPoS/index.html).\n-   RPC Server: A remote procedure call (RPC) server is used to interact with Substrate nodes.\n\nThere are several files in the `node` directory - take special note of the following:\n\n-   [`chain_spec.rs`](./node/src/chain_spec.rs): A\n    [chain specification](https://substrate.dev/docs/en/knowledgebase/integrate/chain-spec) is a\n    source code file that defines a Substrate chain's initial (genesis) state. Chain specifications\n    are useful for development and testing, and critical when architecting the launch of a\n    production chain. Take note of the `development_config` and `testnet_genesis` functions, which\n    are used to define the genesis state for the local development chain configuration. These\n    functions identify some\n    [well-known accounts](https://substrate.dev/docs/en/knowledgebase/integrate/subkey#well-known-keys)\n    and use them to configure the blockchain's initial state.\n-   [`service.rs`](./node/src/service.rs): This file defines the node implementation. Take note of\n    the libraries that this file imports and the names of the functions it invokes. In particular,\n    there are references to consensus-related topics, such as the\n    [longest chain rule](https://substrate.dev/docs/en/knowledgebase/advanced/consensus#longest-chain-rule),\n    the [Aura](https://substrate.dev/docs/en/knowledgebase/advanced/consensus#aura) block authoring\n    mechanism and the\n    [GRANDPA](https://substrate.dev/docs/en/knowledgebase/advanced/consensus#grandpa) finality\n    gadget.\n\nAfter the node has been [built](#build), refer to the embedded documentation to learn more about the\ncapabilities and configuration parameters that it exposes:\n\n```shell\n./target/release/node-template --help\n```\n\n### Runtime\n\nIn Substrate, the terms\n\"[runtime](https://substrate.dev/docs/en/knowledgebase/getting-started/glossary#runtime)\" and\n\"[state transition function](https://substrate.dev/docs/en/knowledgebase/getting-started/glossary#stf-state-transition-function)\"\nare analogous - they refer to the core logic of the blockchain that is responsible for validating\nblocks and executing the state changes they define. The Substrate project in this repository uses\nthe [FRAME](https://substrate.dev/docs/en/knowledgebase/runtime/frame) framework to construct a\nblockchain runtime. FRAME allows runtime developers to declare domain-specific logic in modules\ncalled \"pallets\". At the heart of FRAME is a helpful\n[macro language](https://substrate.dev/docs/en/knowledgebase/runtime/macros) that makes it easy to\ncreate pallets and flexibly compose them to create blockchains that can address\n[a variety of needs](https://www.substrate.io/substrate-users/).\n\nReview the [FRAME runtime implementation](./runtime/src/lib.rs) included in this template and note\nthe following:\n\n-   This file configures several pallets to include in the runtime. Each pallet configuration is\n    defined by a code block that begins with `impl $PALLET_NAME::Config for Runtime`.\n-   The pallets are composed into a single runtime by way of the\n    [`construct_runtime!`](https://crates.parity.io/frame_support/macro.construct_runtime.html)\n    macro, which is part of the core\n    [FRAME Support](https://substrate.dev/docs/en/knowledgebase/runtime/frame#support-library)\n    library.\n\n### Pallets\n\nThe runtime in this project is constructed using many FRAME pallets that ship with the\n[core Substrate repository](https://github.com/paritytech/substrate/tree/master/frame) and a\ntemplate pallet that is [defined in the `pallets`](./pallets/template/src/lib.rs) directory.\n\nA FRAME pallet is compromised of a number of blockchain primitives:\n\n-   Storage: FRAME defines a rich set of powerful\n    [storage abstractions](https://substrate.dev/docs/en/knowledgebase/runtime/storage) that makes\n    it easy to use Substrate's efficient key-value database to manage the evolving state of a\n    blockchain.\n-   Dispatchables: FRAME pallets define special types of functions that can be invoked (dispatched)\n    from outside of the runtime in order to update its state.\n-   Events: Substrate uses [events](https://substrate.dev/docs/en/knowledgebase/runtime/events) to\n    notify users of important changes in the runtime.\n-   Errors: When a dispatchable fails, it returns an error.\n-   Config: The `Config` configuration interface is used to define the types and parameters upon\n    which a FRAME pallet depends.\n\n[1]: https://github.com/substrate-developer-hub/substrate-node-template\n[2]: https://github.com/rayniel95/apps\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frayniel95%2Frainyelcert-node","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frayniel95%2Frainyelcert-node","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frayniel95%2Frainyelcert-node/lists"}