Giter Club home page Giter Club logo

extended-parachain-template's Introduction

Extended Parachain Template

Check Build

The Extended Parachain Template is a ready-to-use parachain template, pre-configured with the Assets pallet, a simple Governance system (Collective & Motion pallets), and other useful base features.

This is a solid starting point for most Parachain projects as it is a more feature-rich alternative to the base Substrate Parachain Template (which it is derived from).

This template is maintained by the Delivery Services team at Parity.

🚀 Getting Started

🦀 Rust Setup

First, complete the basic Rust setup instructions.

🔧 Build

Clone the extended parachain template repository:

git clone https://github.com/paritytech/extended-parachain-template

Use the following command to build the node without launching it:

cargo build --release

🕸️ Run a local network

Next you will need a compatible release of Polkadot to run a testnet. You may also want to use Zombienet (available for Linux and MacOS) for spinning up a testnet:

You can find linux and macOS executables of the Zombienet CLI here:

https://github.com/paritytech/zombienet/releases Download the Zombienet CLI according to your operating system.

Tip: If you want the executable to be available system-wide then you can follow these steps (otherwise just download the executable to your working directory):

wget https://github.com/paritytech/zombienet/releases/download/v1.3.30/zombienet-macos
chmod +x zombienet-macos 
cp zombienet-macos /usr/local/bin

Make sure Zombienet CLI is installed correctly:

./zombienet-macos --help

You should see some similar output:

Usage: zombienet [options] [command]

Options:
  -c, --spawn-concurrency <concurrency>  Number of concurrent spawning process to launch, default is 1
  -p, --provider <provider>              Override provider to use (choices: "podman", "kubernetes", "native")
  -m, --monitor                          Start as monitor, do not auto cleanup network
  -h, --help                             display help for command

Commands:
  spawn <networkConfig> [creds]          Spawn the network defined in the config
  test <testFile> [runningNetworkSpec]   Run tests on the network defined
  setup <binaries...>                    Setup is meant for downloading and making dev environment of Zombienet ready
  version                                Prints zombienet version
  help [command]                         display help for command

You may use a reference implementation from the folder zombienet-config or make your own. More instructions here: Simulate parachains in a test network

👉 Learn more about parachains here, and parathreads here.

🧙 Learn about how to use this template and run your own parachain testnet for it in the Devhub Cumulus Tutorial.

🏛 Governance

Parachain governance is a very crucial topic that goes beyond using sudo for privileged calls. Read our Governance Explainer here

extended-parachain-template's People

Contributors

alexd10s avatar ayushmishra2005 avatar bernardoaraujor avatar daanvdplas avatar dependabot[bot] avatar ducksblock avatar evilrobot-01 avatar khssnv avatar moliholy avatar peterwht avatar stiiifff avatar valentinfernandez1 avatar weezy20 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

extended-parachain-template's Issues

Adding pallet-contracts sanity check

Hi,

We want to use !ink4.0 using the extended-parachain-template.

We have got no errors in extended-parachain-template for the time being. This is only to make sure that we did not miss something silly.

image

We have created a default "contract.rs" configuration for devnet and mainnet.

contract.rs

use crate::{
	constants::currency::deposit, Balance, Balances, RandomnessCollectiveFlip, Runtime,
	RuntimeCall, RuntimeEvent, RuntimeHoldReason, Timestamp,
};
use frame_support::{
	parameter_types,
	traits::{ConstBool, ConstU32, Nothing},
};
use pallet_contracts::{
	migration::{v12, v13, v14, v15},
	weights::SubstrateWeight,
	Config, DebugInfo, DefaultAddressGenerator, Frame, Schedule,
};
use sp_runtime::Perbill;

pub use parachains_common::AVERAGE_ON_INITIALIZE_RATIO;

// Prints debug output of the `contracts` pallet to stdout if the node is
// started with `-lruntime::contracts=debug`.
pub const CONTRACTS_DEBUG_OUTPUT: DebugInfo = DebugInfo::UnsafeDebug;

parameter_types! {
	pub const DepositPerItem: Balance = deposit(1, 0);
	pub const DepositPerByte: Balance = deposit(0, 1);
	pub const DefaultDepositLimit: Balance = deposit(1024, 1024 * 1024);
	pub MySchedule: Schedule<Runtime> = Default::default();
	pub CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(30);
}

impl Config for Runtime {
	type Time = Timestamp;
	type Randomness = RandomnessCollectiveFlip;
	type Currency = Balances;
	type RuntimeEvent = RuntimeEvent;
	type RuntimeCall = RuntimeCall;
	/// The safest default is to allow no calls at all.
	///
	/// Runtimes should whitelist dispatchables that are allowed to be called from contracts
	/// and make sure they are stable. Dispatchables exposed to contracts are not allowed to
	/// change because that would break already deployed contracts. The `Call` structure itself
	/// is not allowed to change the indices of existing pallets, too.
	type CallFilter = Nothing;
	type DepositPerItem = DepositPerItem;
	type DepositPerByte = DepositPerByte;
	type DefaultDepositLimit = DefaultDepositLimit;
	type WeightPrice = pallet_transaction_payment::Pallet<Self>;
	type WeightInfo = SubstrateWeight<Self>;
	type ChainExtension = ();
	type Schedule = MySchedule;
	type CallStack = [Frame<Self>; 5];
	type AddressGenerator = DefaultAddressGenerator;
	type MaxCodeLen = ConstU32<{ 123 * 1024 }>;
	type MaxStorageKeyLen = ConstU32<128>;
	type UnsafeUnstableInterface = ConstBool<true>;
	type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>;
	type MaxDelegateDependencies = ConstU32<32>;
	type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
	type Migrations = (
		v12::Migration<Runtime, Balances>,
		v13::Migration<Runtime>,
		v14::Migration<Runtime, Balances>,
		v15::Migration<Runtime>,
	);
	type RuntimeHoldReason = RuntimeHoldReason;
	type Debug = ();
	type Environment = ();
}

We have added the below lines in cargo.toml for devnet and mainnet.

pallet-contracts = { workspace = true, default-features = false }
pallet-contracts-primitives = { workspace = true, default-features = false }

[features]
default = ["std"]
std = [
   (...)
   "pallet-contracts-primitives/std",
   "pallet-contracts/std",
]

runtime-benchmarks = [
    (...)
   "pallet-contracts/runtime-benchmarks",
]

try-runtime = [
  (...)
  "pallet-contracts/try-runtime",
]

And finally in the workspace root cargo.toml

cargo.toml

[workspace.dependencies]
(...)
pallet-contracts = { version = "24.0.0", default-features = false }
pallet-contracts-primitives = { version = "27.0.0", default-features = false }
(...)

I am assuming that this is it. No more configuration is need it.

Cheers,

Change SyncStrategy from SyncStrategy::Normal to SyncStrategy::Parachain

https://github.com/paritytech/extended-parachain-template/blob/frontier/node/src/service.rs#L334

It's preferred to set MappingSyncWorker to use SyncStrategy::Parachain as this is a cumulus based parachain and this variant prevents "confusing" the MappingSyncWorker due to blocks being imported multiple times by cumulus and only being marked best on the second time. Relevant logic here:
https://github.com/paritytech/frontier/blob/master/client/mapping-sync/src/lib.rs#L158-L159

Review EPT M1 deliverables

Acceptance criteria for EPT milestone 1.

Main & Frontier branches

  • The README file contains clear instructions on how to use the template
  • We can generate a new parachain project based off the EPT template using the "Use this template" button on the project.
  • The template project builds & tests are passing (GitHub action).

Main branch

  • The main branch is up-to-date with the Polkadot v0.9.36 version.

Frontier branch

  • The frontier branch is up-to-date with the Polkadot v0.9.37 version.

When the dev node is running locally:

  • it is possible to connect to it with a newly created account in Metamask.
  • it is possible to deploy a simple Solidity smart contract (using typical Solidity dev tools e.g. Truffle, HardHat), and interact with it (using MetaMask, or Truffle / HardHat).
  • it is possible to debug smart contract methods using the EVM debug trace API.

Safe Mode capability

Having the ability to temporarily pause transfers & normal operations on a live parachain is a valuable mechanism, when an issue / attack occurs. This is especially useful during the launch period of a parachain whereby the runtime code might not always have been battle-tested yet. Past this initial period, the chain’s Governance body (or Sudo account(s)) could decide to remove this capability to fully decentralize the network. The Substrate FRAME library contains the SafeMode & TxPause pallets which allow to implement such a mechanism.

  • Integrate the FRAME SafeMode & TxPause pallets with sane defaults in both devnet & mainnet runtimes (disabled by default in both runtimes).
  • SafeMode should only allow balance transfers as whitelisted call. Permissionless operations (enter, extend) should be disabled. Only a privileged origin can enable / disable safe mode: ForceEnterOrigin, ForceExtendOrigin & ForceExitOrigin to be configured as the Root origin (Sudo).
  • TxPause PauseOrigin & UnpauseOrigin to be configured as the Root origin (Sudo).

Depends on #71

Separate Devnet and Mainnet

Most parachains will have separate runtimes for Devnet and Mainnet. This template should come prebuilt with this separation to reduce friction for new parachain teams.

  • Create new runtime folder devnet
    • Set spec_name for devnet
    • set impl_name for devnet
    • set Cargo.toml name for devnet
  • Create new runtime folder mainnet
    • Set spec_name for mainnet
    • set impl_name for mainnet
    • set Cargo.toml name for mainnet
  • Create new runtime folder common
  • Update command.rs and chain_spec.rs to include devnet and mainnet
  • Add RuntimeResolver to client to choose between devnet and mainnet
    - Watr-Protocol/watr@b285217
    - Watr-Protocol/watr@ce31560

Add Scheduler pallet

Support for scheduled chain operations is a basic capability that all parachains should offer out-of-the-box. The pallet should be configured with a ScheduleOrigin of EnsureRoot. This provides the capability to perform scheduled Runtime upgrades from either a typical Multisig Sudo account, or a Governance origin.

  • Add FRAME Scheduler pallet to devnet & mainnet runtime.

Depends on #58

[CI] Build & publish collator Docker image

Build and publish (collator) node Docker images when a new release is created on the repository, and publish the images to a Docker registry (either the GitHub Docker registry, or an external one; make if configurable in the GitHub action workflow).

Fix template XCM config

The current XCM configuration, derived from the Substrate parachain template, assumes that the chain is using the relay chain’s token as its own token, and allows teleport but disallow reserve-based transfer operations. This configuration is not a sane default for parachain templates (this has been previously reported on the Cumulus repo). The XCM configuration should assume that the chain uses its own native token, and that XCM teleports are disabled.

  • The LocalAssetTransactor should use a SelfReserve instead of the RelayLocation (see example in Trappist).
  • In pallet_xcm Config, XcmTeleportFilter should be set to Nothing, and XcmReserveTransferFilter set to Evreything.

[CI] Try-runtime task

Include the try-runtime CI task from Trappist, which allows to run a try-runtime operation for PRs marked with a “migration” label. The task should be disabled, because it needs access to a live RPC node, but should come with comments explaining how to configure it once the project has a live testnet / mainnet.

Update README

Remove the generic description about the Cumulus parachain template and provide:

  • a description of the Extended Parachain template project
  • instructions on how to get started using it
  • a license (can be Unlicensed)

cannot find macro `vec` in this scope and mismatched types

I am just now upgrading my chain to polkadot-v1.0.0 where I am using extend-parachain-template but I got this issue while build. Someone please give some advice why I am getting this.

error: cannot find macro `vec` in this scope
   --> /Users/ganesholi/.cargo/git/checkouts/substrate-7e08433d4c370a21/ff24c60/frame/assets/src/functions.rs:702:46
    |
702 |         let mut dead_accounts: Vec<T::AccountId> = vec![];
    |                                                    ^^^
    |
help: consider importing one of these items
    |
20  + use codec::alloc::vec;
    |
20  + use scale_info::prelude::vec;
    |
20  + use sp_std::vec;
    |

error[E0308]: mismatched types
   --> /Users/ganesholi/.cargo/git/checkouts/substrate-7e08433d4c370a21/ff24c60/frame/assets/src/functions.rs:713:32
    |
32  | impl<T: Config<I>, I: 'static> Pallet<T, I> {
    |      - this type parameter
...
713 |                     if dead_accounts.len() >= (max_items as usize) {
    |                                               ^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found `usize`
    |
    = note: expected type parameter `T`
                         found type `usize`

   Compiling frame-support v4.0.0-dev (https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#ff24c60a)
   Compiling sp-consensus v0.10.0-dev (https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#ff24c60a)
For more information about this error, try `rustc --explain E0308`.
error: could not compile `pallet-assets` (lib) due to 2 previous errors
warning: build failed, waiting for other jobs to finish...
ganesholi@Ganeshs-MacBook-Air xcav-parachain % 

[CI] Include build badge in README

Include a build badge in the project’s README to show the build status of the latest PR / commit that was merged into the project’s main branch.

Add Preimage pallet

The Preimage pallet allows for the users and the runtime to store the preimage of a hash on chain. This can be used by other pallets for storing and managing large byte-blobs.
It is typically used in conjunction with Governance -related functionalities, and also with the Scheduler pallet.

  • Add FRAME Preimage pallet to devnet & mainnet runtime.

Upgrade to Polkadot SDK v1.1.0

EPT is currently up-to-date with the Polkadot v1.0.0 release. The upcoming v1.1.0 release is the first release based on the new Polkadot SDK GitHub mono-repository. It also brings some useful additional functionality to the Substrate FRAME library, notably the SafeMode and TxPause pallets (which we want to integrate in the EPT template).

Improve Github Actions

Problem: We are running out of disk space by the time the GH actions reaches the Ensure Benchmarking Compiles step. This is annoying as we have limited disk space and running each step without caching build artifacts can take up too much time.

PR #34

Add Multisig pallet

Support for Multisig accounts is a basic capability that all parachains should offer out-of-the-box.

  • Add FRAME Multisig pallet to devnet & mainnet runtime.

Upgrade to Polkadot v0.9.40

Update Extended Parachain Template from Polkadot release v0.9.37 to release v0.9.40.

See similar update on Trappist repo, with some valuable insights.

Thread 'main' panicked at 'Expected Ok(_).

I am implementing pallet-staking in extend-parachain-template. Everything works fine while building chain but while running in dev mode using ./target/release/parachain-template-node --dev this command, I got below error even though I have implemented stake inside GenesisConfig. Someone please help what I am doing wrong?

ganesholi@Ganeshs-MacBook-Air xcav-parachain % ./target/release/parachain-template-node --dev
2023-09-04 15:29:15 Parachain Collator Template    
2023-09-04 15:29:15 ✌️  version 0.9.420-df8ee1315d3    
2023-09-04 15:29:15 ❤️  by Anonymous, 2020-2023    
2023-09-04 15:29:15 📋 Chain specification: Development    
2023-09-04 15:29:15 🏷  Node name: tough-nose-3849    
2023-09-04 15:29:15 👤 Role: AUTHORITY    
2023-09-04 15:29:15 💾 Database: RocksDb at /var/folders/q3/d699hkpx49xfy236ph7sltr40000gn/T/substratejW2MvL/chains/dev/db/full    
2023-09-04 15:29:15 ⛓  Native runtime: devnet-1000 (devnet-0.tx1.au1)    
2023-09-04 15:29:16 assembling new collators for new session 0 at #0    
2023-09-04 15:29:16 assembling new collators for new session 1 at #0    

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

Version: 0.9.420-df8ee1315d3

   0: backtrace::capture::Backtrace::new
   1: sp_panic_handler::set::{{closure}}
   2: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/alloc/src/boxed.rs:2007:9
      std::panicking::rust_panic_with_hook
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panicking.rs:709:13
   3: std::panicking::begin_panic_handler::{{closure}}
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panicking.rs:597:13
   4: std::sys_common::backtrace::__rust_end_short_backtrace
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/sys_common/backtrace.rs:151:18
   5: rust_begin_unwind
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panicking.rs:593:5
   6: core::panicking::panic_fmt
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/panicking.rs:67:14
   7: <pallet_staking::pallet::pallet::GenesisConfig<T> as frame_support::traits::hooks::GenesisBuild<T>>::build
   8: environmental::using
   9: sp_state_machine::basic::BasicExternalities::execute_with_storage
  10: <devnet_runtime::GenesisConfig as sp_runtime::BuildStorage>::assimilate_storage
  11: <sc_chain_spec::chain_spec::ChainSpec<G,E> as sp_runtime::BuildStorage>::assimilate_storage
  12: sp_runtime::BuildStorage::build_storage
  13: cumulus_client_cli::generate_genesis_block
  14: tokio::runtime::park::CachedParkThread::block_on
  15: tokio::runtime::context::runtime::enter_runtime
  16: tokio::runtime::runtime::Runtime::block_on
  17: sc_cli::runner::Runner<C>::run_node_until_exit
  18: parachain_template_node::command::run
  19: std::sys_common::backtrace::__rust_begin_short_backtrace
  20: std::rt::lang_start::{{closure}}
  21: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/ops/function.rs:284:13
      std::panicking::try::do_call
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panicking.rs:500:40
      std::panicking::try
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panicking.rs:464:19
      std::panic::catch_unwind
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panic.rs:142:14
      std::rt::lang_start_internal::{{closure}}
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/rt.rs:148:48
      std::panicking::try::do_call
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panicking.rs:500:40
      std::panicking::try
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panicking.rs:464:19
      std::panic::catch_unwind
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panic.rs:142:14
      std::rt::lang_start_internal
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/rt.rs:148:20
  22: _main


Thread 'main' panicked at 'Expected Ok(_). Got Err(
    Module(
        ModuleError {
            index: 47,
            error: [
                4,
                0,
                0,
                0,
            ],
            message: Some(
                "EmptyTargets",
            ),
        },
    ),
)', /Users/ganesholi/.cargo/git/checkouts/substrate-7e08433d4c370a21/ff24c60/frame/staking/src/pallet/mod.rs:652

This is a bug. Please report it at:

        https://github.com/paritytech/cumulus/issues/new

ganesholi@Ganeshs-MacBook-Air xcav-parachain % 

Unable to export genesis state to the local Relay chain

Hi,
I follow the instructions from
https://docs.substrate.io/tutorials/build-a-parachain/connect-a-local-parachain/
in order to register a freshly forked extended-parachain-template on a locally running Relay chain.
I get the following printout upon trying to register the parachain on the local relay chain:

./target/release/parachain-template-node export-genesis-state --chain raw-parachain-chainspec.json para-2000-genesis-state
2023-09-10 09:33:24 Essential task `transaction-pool-task-1` failed. Shutting down service.    
2023-09-10 09:33:24 Essential task `basic-block-import-worker` failed. Shutting down service.    
2023-09-10 09:33:24 Essential task `transaction-pool-task-0` failed. Shutting down service.    
2023-09-10 09:33:24 Essential task `txpool-background` failed. Shutting down service.

The relay chain runs with a fresh db starting from block 0.
I conducted the same procedure with a substrate-parachain-template and haven't faced the issue.
After trying a few times I see, that it's 100% reproducible on my machine.
Here is the snippet of the chainspec json file for the extended-parachain-template:

{
  "name": "Development Local Testnet",
  "id": "dev_local_testnet",
  "chainType": "Local",
  "bootNodes": [],
  "telemetryEndpoints": null,
  "protocolId": "template-local",
  "properties": {
    "ss58Format": 42,
    "tokenDecimals": 12,
    "tokenSymbol": "UNIT"
  },
  "relay_chain": "rococo-local",
  "para_id": 2000,
  "codeSubstitutes": {},
...

The chainspec of the substrate-parachain-template that registers successfully looks similar:

{
  "name": "Local Testnet",
  "id": "local_testnet",
  "chainType": "Local",
  "bootNodes": [],
  "telemetryEndpoints": null,
  "protocolId": "template-local",
  "properties": {
    "ss58Format": 42,
    "tokenDecimals": 12,
    "tokenSymbol": "UNIT"
  },
  "relay_chain": "rococo-local",
  "para_id": 2000,
  "codeSubstitutes": {},
  "genesis": {
    "runtime": {
...

I have attached both full plain chainspec files.

plain-parachain-template-chainspec.txt
plain-extended-parachain-template-chainspec.txt

fix: include sudo weights

When ept is updated to polkadot 9.43 sudo weights have to be included to the runtime since they have been added since (ref).

Minimal AssetHub integration

Provide an out-of-the-box configuration of the chain’s runtime to integrate with the AssetHub common-good parachain.

This entails:

  • Implement a Fungible adapter for foreign assets (on the AH) in the XCM configuration.
  • Implement logic to map a foreign asset to a local (derivative) one.
  • Allow reserve-based transfer operations for foreign assets.

Note: this logic could be put in a distinct asset_hub.rs file to cleanly separate it from the rest of the runtime logic.

Configure example Multisig Sudo account in mainnet runtime

A single account Sudo is a practice that should be discouraged as it poses significant risk from a security & operational perspective. We should encourage the use of a Multisig Sudo account as the secure default. The EPT should come built-in with a configuration for a 2-out-of-3 Multisig sudo account for the mainnet runtime. A documentation item accompanying could provide insights on how to transition from a Multisig Sudo account to a Council-based Governance scheme (using the already built-in Collective & Motion pallets).

  • Configure an example 2-out-of-3 Multisig sudo account for the mainnet runtime
  • Add a documentation page that explains how to transition from a Multisig Sudo account to a Council-based Governance scheme (using the already built-in Collective & Motion pallets).

Depends on #56

Add XCM Fungible adapter

The current XCM configuration, derived from the Substrate parachain template, does not provide a Fungible adapter which means that no XCM operations are possible on the local chain’s fungible assets (that exist within the built-in Assets pallet).

  • Add a LocalFungiblesTransactor (see an example one in the Trappist project) to the XCM executor as AssetTransactor (along with the existing LocalAssetTransactor).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.