Coder Social home page Coder Social logo

pontem-network / pontem Goto Github PK

View Code? Open in Web Editor NEW
77.0 22.0 43.0 4.03 MB

๐Ÿš€ Pontem Parachain node with Move VM onboard.

Home Page: https://pontem.network

License: Apache License 2.0

Makefile 0.11% Rust 29.97% Shell 0.20% Dockerfile 0.09% Nix 0.16% Handlebars 0.11% Move 69.37%
substrate diem libra polkadot pontem-network

pontem's Introduction

Pontem

Warning: The repository contains a very out-of-date Move VM version. It can contain bugs or security issues. Use at your own risk.

Pontem parachain node with Move VM pallet on board.

  • Pontem docs - if you want to learn about Pontem network.
  • Validator docs - if you want to launch a validator node.
  • Bootstrap - if you want to up node quickly (not for development).

Local Relaychain & Parachain Launch

Current version built with Nimbus consensus and Parachain Staking implementation. Requires relay chain to work correctly.

Requirements

Build

To build Pontem node run the following commands:

cd pontem
make init
make build

See built binary at:

./target/release/pontem

There are several options to launch Pontem local parachain:

Using polkadot-launch

Install polkadot-launch.

Note: you must have polkadot node v0.9.18 compiled and built placed in ../polkadot/target/release/. To use different localion you can modify ./launch-config.json.

Create keystore path for Pontem:

mkdir -p ~/.pontem/keystore-1 # Base path

Add Nimbus key:

# Use "//Alice" for URI.
./target/release/pontem key insert --keystore-path ~/.pontem/keystore-1 --key-type nmbs --scheme sr25519
# run pontem-node
polkadot-launch ./launch-config.json

Wait for an minute.

Observe 9946.log to verify that the node was launched successfully and is producing blocks, also you can use Web UI.

tail -f ./9946.log

Using polkadot-launch via docker-compose

Build container:

cd pontem
docker-compose build

Launching services:

docker-compose up -d

Log files are in folder docker-launch.

In the docker-compose.yml file, you can set the required versions of polkadot and pontem by specifying them in POLKADOT_VERSION and PONTEM_VERSION, respectively. (note: if you change versions in docker-compose.yaml or change the .build/launch.Dockerfile, you need to rerun the docker-compose build command).

You can connect using the following ports:

127.0.0.1:9944 # Alice relaychain
127.0.0.1:9946 # Alice parachain

Manually

Build Polkadot:

git clone https://github.com/paritytech/polkadot.git
cd polkadot
git fetch origin
git checkout release-v0.9.18
cargo build --release

Launch Polkadot Relay Chain:

./target/release/polkadot build-spec --chain rococo-local --disable-default-bootnode --raw > rococo-local-cfde.json
./target/release/polkadot --chain rococo-local-cfde.json --alice --tmp
./target/release/polkadot --chain rococo-local-cfde.json --bob --tmp --port 30334 # In a separate terminal

Build Pontem node and then create keystore path for Pontem:

mkdir -p ~/.pontem/keystore-1 # Base path

Add Nimbus key:

# Use "//Alice" for URI.
./target/release/pontem key insert --keystore-path ~/.pontem/keystore-1 --key-type nmbs --scheme sr25519

Launch parachain node as collator:

./target/release/pontem export-genesis-state --chain=local 2000 > genesis-state
./target/release/pontem export-genesis-wasm > genesis-wasm
./target/release/pontem --collator --tmp --keystore-path ~/.pontem/keystore-1 --chain=local --port 40335 --ws-port 9946 -- --execution wasm --chain ../polkadot/rococo-local-cfde.json --port 30335

Register the parachain:

  1. Navigate to sudo UI in Relay Chain.
  2. Choose parasSudoWrapper.
  3. Choose sudoScheduleParaInitialize(id, genesis) method.
  4. Change id to 2000.
  5. Upload genesis-state to genesisHead field.
  6. Upload gensis-wasm to validationCode field.
  7. Change parachain field to Yes.
  8. Send transaction.
  9. Restart pontem-node.

Metadata

Metadata for Polkadot JS can be found in repository containing types.

  • Current amount of top collator is 8.
  • Block time is 12 seconds.
  • There is 1 hour rounds.

Connect as a new collator

Create keystore path for the new key:

mkdir ~/.pontem/keystore-2 # Base path

Add new Nimbus key:

# Use "//Bob" for URI.
./target/release/pontem key insert --keystore-path ~/.pontem/keystore-2 --key-type nmbs --scheme sr25519

Get your public key:

# Use "//Bob" for dev purposes URI.
./target/release/pontem key inspect

You will see something like:

Secret Key URI `//Bob` is account:
Secret seed:       0x02ca07977bdc4c93b5e00fcbb991b4e8ae20d05444153fd968e04bed6b4946e7
Public key (hex):  0xb832ced5ca2de9fe76ef101d8ab1b8dd778e1ab5a809d019c57b78e45ecbaa56
Public key (SS58): 5GEDm6TY5apP4bhwuTtTzA7z9vHbCL1V2D5nE8sPga6WKhNH
Account ID:        0xb832ced5ca2de9fe76ef101d8ab1b8dd778e1ab5a809d019c57b78e45ecbaa56
SS58 Address:      5GEDm6TY5apP4bhwuTtTzA7z9vHbCL1V2D5nE8sPga6WKhNH

Copy Public key (hex) as your public key, it's going to be your validator public key. Now you need to map your public key with your account.

Send new transaction to map your public key with your account:

  1. Navigate to extrinsics.
  2. Choose authorMapping pallet.
  3. Choose addAssociation(author_id) function.
  4. Put your public key in author_id field.
  5. Send transaction from your account.

Now create your validator:

  1. Navigate to extrinsics.
  2. Choose parachainStaking pallet.
  3. Choose joinCandidates(bond, candidate_count) function.
  4. Put amount to bond in PONT tokens.
  5. For candidate_count use 1.
  6. Send transaction.

Now time to launch your node.

If you used polkadot-launch to launch everything:

/target/release/pontem --collator \
     --tmp \
    --keystore-path ~/.pontem/keystore-2  \
    --chain=local \
    --port 40338 \
    --ws-port 9947 \
    --bootnodes <bootnode> \
    -- --execution wasm --chain ./rococo-local.json --port 40336

Replace bootnode with peer address from result of following command:

cat 9946.log | grep 40335 # Something like: /ip4/127.0.0.1/tcp/40335/p2p/12D3KooWM1a6mBNyvZwbN5T3sDuYuxgxmNoj83CnFqaHJzaB8GYV

If you used manual method:

/target/release/pontem --collator \
    --tmp \
    --keystore-path ~/.pontem/keystore-2  \
    --chain=local \
    --port 40338 \
    --ws-port 9947 \
    --bootnodes <bootnode> \
    -- --execution wasm --chain ../polkadot/rococo-local-cfde.json --port 40336

Good documentation also can be found in Moonriver/Moonbeam Docs.

Running in dev-mode

There is a possibility to run a single node in development mode, without any consensus involved.

Add --dev-service flag to cargo run command to run a single node with disabled consensus:

IMPORTANT NOTE: the node with enabled --dev-service flag generating blocks when needed (e.g. when a new transaction appears).

./target/release/pontem --dev --dev-service --tmp

Use --sealing argument to select sealing mode:

  1. instant (default). Blocks a produced automatically for each transaction
  2. <number>. Blocks are produced once per number milliseconds

Documentation

See Move VM Pallet documentation.

XCM

The XCM implemented includes assets transferring between Parachains and Relaychain using XTokens pallet.

  • Transfers from Relaychain to Parachain happens with reserveTransferAssets.
  • XCM teleport and executions are currently disabled.
  • Supports PONT and KSM tokens.

Dev Relaychain

In case you want to run node with dev Relaychain (e.g. using polkadot-launch), after launching Relaychain send transaction using sudo account:

  1. Navigate to sudo.
  2. Choose xcmPallet pallet.
  3. Choose forceDefaultXcmVersion(maybeXcmVersion) function.
  4. Enable option maybeXcmVersion.
  5. Put 2 into the maybeXcmVersion field.
  6. Send transaction.

Now you can use XCM.

LICENSE

See LICENSE.

pontem's People

Contributors

anthonymikh avatar boozook avatar borispovod avatar cab404 avatar mrz1703 avatar olegvg avatar rig410 avatar singulared avatar tikhono avatar vitvakatu avatar vladimirovmm 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  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  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  avatar  avatar

Watchers

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

pontem's Issues

Could not decode `Call`, variant doesn't exist

Ubuntu 20.04 LTS
Version: pontem 0.4.3-f0105ad-x86_64-linux-gnu

2021-12-16 16:32:57 [Parachain] ๐Ÿ’” Verification failed for block 0x8c8d8310c505b4e59fb90d481d8b34a382c404e363a1493f0fcb182a769f784a received from peer: 12D3KooWCAtpFT3iir1hGADAYPXmPmYmfbzgsnq6yqfr8reNBWTG, "Application(Execution(ApiError(FailedToConvertParameter { function: "check_inherents", parameter: "block", error: Error { cause: Some(Error { cause: Some(Error { cause: None, desc: "Could not decode Call, variant doesn't exist" }), desc: "Could not decode Call::System.0" }), desc: "Could not decode Block::extrinsics" } })))"

Restrict the usage of the move-root signer

If and when VM gives possibilities to send tx by root signer we should implement restrictions and its management to control who can send these such transactions.

  • ensure root or configured acc if tx by root
  • configure acc to control move-root with genesis-config (build storage)
  • configure acc to control move-root with democracy

rel issues: Dove#105, VM#43.
rel PRs: Dove#108, VM#44.

Refactor balances (value * PONT)

Description:

Currently we are using the following approach when announcing balances Balance = value * PONT.

Example:

pub const MinimumDeposit: Balance = 100 * PONT;

Would be nice to replace this calls with function, e.g.:

CurrencyId::PONT.to_units(1.5)
CurrencyId::KSM.to_units(100.0)

After refactoring it should looks so:

pub const MinimumDeposit: Balance = CurrencyId::PONT.to_units(100.0);

Requirenments:

  • Function should return Balance (u64)
  • We should care about Balance in u64 if we overflow it, we should return u64
  • We should care about units smaller than minimal in e.g we provide 1.0008 for currency with 3 decimals, we should have 1000 as u64 return)
  • All places where we used old-fashion variant should be converted

Move VM pallet extrinsics should also take additional weight itself

We should add additional weight to sp-mvm pallet extrinsics. As we also spend CPU and Memory to initialize VM, etc.

For example, currently extrinsic execute uses dynamic weight only but there's should be a sum of this and sum constant value. That constant value should used as default, if transaction fails for example.

The value of the constant should be empirically chosen for each extrinsic and as starting point it means default 10000. Use runtime-benchmarking for this. Also there's some possibly useful tools: weight-meter and weight-gen.

Also, do not burn fees as it happens now. Move it to treasury.

  • add "default" value for extrinsics
  • add fee present as Config value
  • send and accumulate fees in the treasury

failed to run custom build command for `stdlib v0.1.0

Hi,

We are getting this error when building the node:

error: failed to run custom build command for stdlib v0.1.0 (https://github.com/pontem-network/sp-move-vm.git?rev=a6585179256bcb44c5e1db34201c3a5b6c8e3693#a6585179)

Caused by:
process didn't exit successfully: /home/pontem/pontem/target/release/build/stdlib-eae87de3139b381b/build-script-build (exit status: 101)
--- stdout
cargo:rerun-if-changed=build.rs

--- stderr
Cloning into 'move-stdlib'...
Note: switching to '34cedad7436f7dad6c9a521f3f6199324737d69f'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

git switch -c <new-branch-name>

Or undo this operation with:

git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 34cedad Merge pull request #26 from pontem-network/feature-update-readme-pnt
thread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', /home/pontem/.cargo/git/checkouts/sp-move-vm-1e79a042c2a39ea0/a658517/stdlib/build.rs:26:10
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

Seems like it can't unwrap the dependencie?

Update weight with extrinsics itself

We should add additional weight to our sp-move extrinsics as it takes gas outside VM execution.

Look at our extrinsics, e.g.: execute, publish_module, publish_package, additional weight could be constant or dynamic, based on code.

Refactor test-assets import and usage for pallet

The idea is about new macro where

  • including move assets
  • gen names for files (modules and scripts)
  • gen id by seq number in filename
  • gen enums for modules, scripts and transactions with constructors named using generated names for move assets

This should dramatically simplify the support and modification of tests.

Enable multicurrencies

We should enable multicurrencies, so our node can work both with native balance and tokens, include VM and XCMP.

Refactoring primitives/currencies

Task description

We need to refactor currency.rs.
Currently is quite annoying to add new one, with a lot of hand-crafted-work.

Best way to do it is to wrap it to a macro, in e.g. we can look how Acala implemented similar case (but if we adopt code we should clean up all EVM and other unnecessary stuff)

Definition of done

  • Adding new currency as simple as adding one line of code

Research why toolchain update breaks Pontem node

Current node doesn't work correctly if we update toolchain, for example for 2021-09-12.

It's easy to check:

  1. Change toolchain to 2021-09-12 (use rust-toolchain file).
  2. Build node: make init && make build.
  3. Build polkadot.
  4. Use polkadot-launch to launch parachain and relay chain:
polkadot-launch ./launch-config.json 

You will get error in Pontem node logs, like:

2021-10-21 13:45:00 [Parachain] :exclamation:๏ธ Inherent extrinsic returned unexpected error: Error at calling runtime api: Execution failed: Other("Wasm execution trapped: wasm trap: out of bounds memory access\nwasm backtrace:\n    0: 0x574d5 - <unknown>!cumulus_pallet_parachain_system::relay_state_snapshot::RelayChainStateProof::new::h23864b3fb6168953\n    1: 0x1fe59d - <unknown>!<cumulus_pallet_parachain_system::pallet::Call<T> as frame_support::traits::dispatch::UnfilteredDispatchable>::dispatch_bypass_filter::h1c9f796bc215f2cf\n    2: 0x1f945f - <unknown>!<pontem_runtime::Call as frame_support::traits::dispatch::UnfilteredDispatchable>::dispatch_bypass_filter::h9c13df700fa219ef\n    3: 0x11db47 - <unknown>!<pontem_runtime::Call as sp_runtime::traits::Dispatchable>::dispatch::h923f320dc8bf608a\n    4: 0x1dcedd - <unknown>!frame_executive::Executive<System,Block,Context,UnsignedValidator,AllPallets,COnRuntimeUpgrade>::apply_extrinsic::hbb8e8c25e4649bb9\n    5: 0x21e849 - <unknown>!BlockBuilder_apply_extrinsic\nnote: run with `WASMTIME_BACKTRACE_DETAILS=1` environment variable to display more information\n"). Dropping.

Balance showed on liquidswap doesn't match that wallet showed.

Describe the bug
Balance showed on website doesn't match that wallet showed.

To Reproduce

  1. Connect wallet, request some token from wallet
  2. Go to liquidswap, find your APTOS balance
  3. Balance mismatch.

Snapshot
1659437421578
image

Expected behavior
Balance shoud be the same

Version
The latest release

Consider Move Root Signer Placeholder for Move-transactions

Ensure origin is sudo (ensure_root) for move-transactions (execute_script) if transaction requires root-signer.
So check if move-transaction requires root-signer then check ensure_root and then execute that transaction.
If tx requires root but origin isn't sudoer then reject with error something like "wrong signer".
Ensure root isn't needed if tx doesn't requires root.

  • extrinsic
  • tests

Differences between Pontem's Move implementation and Outmove

This is more of a question rather than an issue. I tried asking in the Telegram, but I guess because I included a link some bot automatically kicked me ๐Ÿคทโ€โ™‚๏ธ

I was curious about the differences of Pontem's Move VM vs outmove (https://github.com/outmove/omv) are. In particular, I think by default Move restricts to who it can send funds to, i.e. addresses need to be generated which AFAIK is changed in outmove. But I'm not very deep into the differences so I'd thought I'd ask directly. Thanks!

We should allow to publish module under root address (0x01)

It's already implemented for publishing packages (see publish_package).

But publish_module function missing it.
We should implement it inside of it, you can look upon publish_package for detals.

Requirenments:

  • Allow to publish module under root (0x01 address).
  • Use T::UpdaterOrigin::ensure_origin to check if root or not.
  • If root -> store module under 0x01 address.
  • If not root -> store under sender address.
  • Cover with tests.

Definition of done

  • You now can use publish_module from root address
  • Tests on publish_module covers both root and non-root senders

Bug report

pontem-node | Hash: given=009fbe46db680acd4e5c78647801a25e470073d379cade26261affb64b9b88ea, expected=02635e1185c1c098658da0a440f73b6cea4b4f86de73f7d2458c0ce5dc7256c2 pontem-node | pontem-node | ==================== pontem-node | pontem-node | Version: 0.4.2-unknown-x86_64-linux-gnu pontem-node | pontem-node | 0: sp_panic_handler::set::{{closure}} pontem-node | 1: std::panicking::rust_panic_with_hook pontem-node | at /rustc/e8cb1a4a567ce88e459ffd431207eff2e0f0ffa5/library/std/src/panicking.rs:626:17 pontem-node | 2: std::panicking::begin_panic::{{closure}} pontem-node | 3: std::sys_common::backtrace::__rust_end_short_backtrace pontem-node | 4: std::panicking::begin_panic pontem-node | 5: frame_executive::Executive<System,Block,Context,UnsignedValidator,AllPallets,COnRuntimeUpgrade>::final_checks pontem-node | 6: tracing::span::Span::in_scope pontem-node | 7: frame_executive::Executive<System,Block,Context,UnsignedValidator,AllPallets,COnRuntimeUpgrade>::execute_block pontem-node | 8: <pontem_runtime::Runtime as sp_api::runtime_decl_for_Core::Core<sp_runtime::generic::block::Block<sp_runtime::generic::header::Header<u32,sp_runtime::traits::BlakeTwo256>,sp_runtime::generic::unchecked_extrinsic::UncheckedExtrinsic<sp_runtime::multiaddress::MultiAddress<<<sp_runtime::MultiSignature as sp_runtime::traits::Verify>::Signer as sp_runtime::traits::IdentifyAccount>::AccountId,()>,pontem_runtime::Call,sp_runtime::MultiSignature,(frame_system::extensions::check_spec_version::CheckSpecVersion<pontem_runtime::Runtime>,frame_system::extensions::check_tx_version::CheckTxVersion<pontem_runtime::Runtime>,frame_system::extensions::check_genesis::CheckGenesis<pontem_runtime::Runtime>,frame_system::extensions::check_mortality::CheckMortality<pontem_runtime::Runtime>,frame_system::extensions::check_nonce::CheckNonce<pontem_runtime::Runtime>,frame_system::extensions::check_weight::CheckWeight<pontem_runtime::Runtime>,pallet_transaction_payment::ChargeTransactionPayment<pontem_runtime::Runtime>)>>>>::execute_block pontem-node | 9: std::panicking::try pontem-node | 10: std::thread::local::LocalKey<T>::with pontem-node | 11: sc_executor::native_executor::WasmExecutor::with_instance::{{closure}} pontem-node | 12: sc_executor::wasm_runtime::RuntimeCache::with_instance pontem-node | 13: <sc_executor::native_executor::NativeElseWasmExecutor<D> as sp_core::traits::CodeExecutor>::call pontem-node | 14: sp_state_machine::execution::StateMachine<B,H,N,Exec>::execute_aux pontem-node | 15: sp_state_machine::execution::StateMachine<B,H,N,Exec>::execute_using_consensus_failure_handler pontem-node | 16: <sc_service::client::call_executor::LocalCallExecutor<Block,B,E> as sc_client_api::call_executor::CallExecutor<Block>>::contextual_call pontem-node | 17: <sc_service::client::client::Client<B,E,Block,RA> as sp_api::CallApiAt<Block>>::call_api_at pontem-node | 18: sp_api::runtime_decl_for_Core::execute_block_call_api_at pontem-node | 19: <pontem_runtime::RuntimeApiImpl<__SR_API_BLOCK__,RuntimeApiImplCall> as sp_api::Core<__SR_API_BLOCK__>>::Core_execute_block_runtime_api_impl pontem-node | 20: sp_api::Core::execute_block_with_context pontem-node | 21: sc_service::client::client::Client<B,E,Block,RA>::prepare_block_storage_changes pontem-node | 22: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll pontem-node | 23: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll pontem-node | 24: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll pontem-node | 25: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll pontem-node | 26: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll pontem-node | 27: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll pontem-node | 28: <futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll pontem-node | 29: <sc_service::task_manager::prometheus_future::PrometheusFuture<T> as core::future::future::Future>::poll pontem-node | 30: <futures_util::future::select::Select<A,B> as core::future::future::Future>::poll pontem-node | 31: <tracing_futures::Instrumented<T> as core::future::future::Future>::poll pontem-node | 32: tokio::runtime::enter::Enter::block_on pontem-node | 33: tokio::runtime::handle::Handle::block_on pontem-node | 34: tokio::runtime::task::core::CoreStage<T>::poll pontem-node | 35: tokio::runtime::task::harness::Harness<T,S>::poll pontem-node | 36: tokio::runtime::blocking::pool::Inner::run pontem-node | 37: std::sys_common::backtrace::__rust_begin_short_backtrace pontem-node | 38: core::ops::function::FnOnce::call_once{{vtable.shim}} pontem-node | 39: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once pontem-node | at /rustc/e8cb1a4a567ce88e459ffd431207eff2e0f0ffa5/library/alloc/src/boxed.rs:1575:9 pontem-node | <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once pontem-node | at /rustc/e8cb1a4a567ce88e459ffd431207eff2e0f0ffa5/library/alloc/src/boxed.rs:1575:9 pontem-node | std::sys::unix::thread::Thread::new::thread_start pontem-node | at /rustc/e8cb1a4a567ce88e459ffd431207eff2e0f0ffa5/library/std/src/sys/unix/thread.rs:72:17 pontem-node | 40: start_thread pontem-node | 41: clone pontem-node | pontem-node | pontem-node | Thread 'tokio-runtime-worker' panicked at 'Storage root must match that calculated.', /root/.cargo/git/checkouts/substrate-7e08433d4c370a21/57346f6/frame/executive/src/lib.rs:503 pontem-node | pontem-node | This is a bug. Please report it at: pontem-node | pontem-node | support.anonymous.an pontem-node | pontem-node |

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.