Giter Site home page Giter Site logo

oss's Introduction

OSS

A REST api for gcoin rpc.

Installation

Requirement

  • Python 2.7
  • virtualenv

Setup

./setup_venv.sh

Configuration

Set up setting.py

cp oss_server/oss_server/settings/setting.py.default oss_server/oss_server/settings/setting.py

Modify setting.py

Secret key

<SECRET_KEY>

This is used to provide cryptographic signing, and should be set to a unique, unpredictable value.

Environment

<ENV>

Fill in develop will enable oss_server/oss_server/settings/develop.py for debug information while running the project.

test: oss_server/oss_server/settings/test.py

It is designed for a standalone unit test process using a in-memory database.

production: oss_server/oss_server/settings/production.py

It disable debug information for production environment.

Allowed hosts

<ALLOW_DOMAIN>

Replacing it with * means it allowed requests from everywhere.

Use * for develop and subdomain format for production environment.

Gcoin rpc

Set up connection of gcoin rpc

GCOIN_RPC = {
    'user': '<GCOIN_RPC_USER>',
    'password': '<GCOIN_RPC_PASSWORD>',
    'host': '<GCOIN_RPC_HOST>',
    'port': '<GCOIN_RPC_PORT>',
}

Database

OSS uses mariadb to store blockchain data. Make sure to create a database named the same as <EXPLORER_DB_NAME>, then migrate with:

./manage.py migrate

DATABASES = {
    'default': {
        'NAME': '<EXPLORER_DB_NAME>',
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '<EXPLORER_DB_HOST>',
        'PORT': '<EXPLORER_DB_PORT>',
        'USER': '<EXPLORER_DB_USER>',
        'PASSWORD': '<EXPLORER_DB_PSSWORD>',
        'CONN_MAX_AGE': 20
    }
}

Sync database with blockchain

<BLK_DIR>

The data forlder, which are usually located under ~/.gcoin/main/blocks

It is the key point for entire OSS project. The Django command called blockupdate will read all the blockchain data under this forlder every second by default and save these data to specified database.

Run ./manage.py blockupdate to sync blockchain indefinitely.

Run unit test

Run ./manage.py test --settings=oss_server.settings.test for a standalone unit test.

Run ./manage.py test will create a test database specified in setting.py and destroy it after compeleting the test.

Run server

Start server

./oss_server/manage.py runserver <address>:<port>

Start services

./manage.py blockupdate
./manage.py txnotify
./manage.py addressnotify

oss's People

Contributors

stanleyding avatar bun919tw avatar benjaminlu avatar lbyyy avatar boolafish avatar jsying avatar jsying13 avatar wubm avatar hanky312 avatar jeremyhd avatar jospehchiu avatar

Watchers

En-Jan Chou avatar  avatar Kordan Ou avatar Shawn Hung avatar James Cloos avatar Don avatar  avatar 王雅人 (masato25) avatar James avatar Hu-Cheng Lee avatar  avatar Chung, Ming-Yen avatar Sean49 avatar Maker Su avatar Chieh Teng Chang avatar morrisChang avatar  avatar Elvis Yu-Jing Lin avatar  avatar Jonah1005 avatar 廖彥智 avatar  avatar  avatar JohnnyHsu avatar  avatar  avatar victai avatar  avatar Y. C. Zhang avatar  avatar  avatar rendybig avatar  avatar Eiffel avatar Hsiu-Yao (Willie) Chang avatar Song-Ren, Huang avatar  avatar kbjiyu avatar Ta-Wei Tu avatar Henry Dai avatar  avatar  avatar  avatar Jiyi Wu avatar

oss's Issues

explorer/v1/addresses/[:address]/balance API會將type=LICENSE的交易也算入餘額

explorer/v1/addresses/[:address]/balance API會將 type=LICENSE 的交易也算入餘額
base/v1/balance/[:address] 不會

實測若要花費 type=LICENSE 的 value,在transaction/prepare API 就會被擋,
因為在 oss_server/base/v1/views.py line 204
utxos = get_rpc_connection().gettxoutaddress(from_address)
就已經抓不到type=LICENSE的utxo

explorer/v1/addresses/[:address]/balance 是否該將type=LICENSE的utxo過濾掉?

統一base和explorer回傳的tx格式

/base/v1/transaction/{tx_hash}
/explorerexplorer/v1/transactions/address/{address}
sample:

base
{  
   "size":831,
   "txid":"38a3453bd218000492765d55b02b0b171c7a95adbfeaea92c6436b57a90841d0",
   "locktime":0,
   "confirmations":556,
   "version":1,
   "hex":"010000000108e5ea1df296047d091f93cb0b1261aa513b032ea0047fc2837c532856bbce4b020000006a47304402205e017a9502c9ad98cc5ebf66e1cf2d18ca0c73afb542b51835d4afff0867dc3202207c325fd4b44799cd4a7254286b499818ba5c885a0e08c6b95c2a5ffc0e20c103012103b7516c9e4d6f2f2b74e0f5e5893d65ca239b3647d29496c95273bd000520d212ffffffff0300e1f5050000000017a914a5e8e052333652edc0baa9d3926eb06af827eca687010000000000000000000000fd45026a4d41027b22736f757263655f636f6465223a202236303630363034303532336636313030303035373562363030313630303038313930353535303562356236306238383036313030323236303030333936303030663330303630363036303430353236303030333537633031303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303039303034363366666666666666663136383036333031373235613062313436303436353738303633333731333033633031343630363635373562363030303536356233663630303035373630353036303732353635623630343035313830383238313532363032303031393135303530363034303531383039313033393066333562336636303030353736303730363037383536356230303562363030303534383135363562363030313630303036303030383238323534303139323530353038313930353535303562353630306131363536323761376137323330353832306436626365653661326333376165616364316439363438623461633630663239396561363333353062623136656135393930393237623861316461616132336430303239222c20226d756c74697369675f61646472657373223a20223347704750696f6648476f4d313953686a756e424e353367545341424c57685a5147222c2022636f6e74726163745f61646472657373223a202235303235313134643364646435336135363239373339663931376235653030373433636639373534227d0000000000bc760f7d8d03001976a91484c5d5e87df109be8d86b76f7dc84812799cefe088ac010000000000000005000000",
   "vin":[  
      {  
         "sequence":4294967295,
         "vout":2,
         "scriptSig":{  
            "hex":"47304402205e017a9502c9ad98cc5ebf66e1cf2d18ca0c73afb542b51835d4afff0867dc3202207c325fd4b44799cd4a7254286b499818ba5c885a0e08c6b95c2a5ffc0e20c103012103b7516c9e4d6f2f2b74e0f5e5893d65ca239b3647d29496c95273bd000520d212",
            "asm":"304402205e017a9502c9ad98cc5ebf66e1cf2d18ca0c73afb542b51835d4afff0867dc3202207c325fd4b44799cd4a7254286b499818ba5c885a0e08c6b95c2a5ffc0e20c10301 03b7516c9e4d6f2f2b74e0f5e5893d65ca239b3647d29496c95273bd000520d212"
         },
         "txid":"4bcebb5628537c83c27f04a02e033b51aa61120bcb931f097d0496f21deae508"
      }
   ],
   "type":"CONTRACT",
   "vout":[  
      {  
         "color":1,
         "scriptPubKey":{  
            "reqSigs":1,
            "type":"scripthash",
            "hex":"a914a5e8e052333652edc0baa9d3926eb06af827eca687",
            "asm":"OP_HASH160 a5e8e052333652edc0baa9d3926eb06af827eca6 OP_EQUAL",
            "addresses":[  
               "3GpGPiofHGoM19ShjunBN53gTSABLWhZQG"
            ]
         },
         "value":100000000,
         "n":0
      },
      {  
         "color":0,
         "scriptPubKey":{  
            "type":"nulldata",
            "hex":"6a4d41027b22736f757263655f636f6465223a202236303630363034303532336636313030303035373562363030313630303038313930353535303562356236306238383036313030323236303030333936303030663330303630363036303430353236303030333537633031303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303039303034363366666666666666663136383036333031373235613062313436303436353738303633333731333033633031343630363635373562363030303536356233663630303035373630353036303732353635623630343035313830383238313532363032303031393135303530363034303531383039313033393066333562336636303030353736303730363037383536356230303562363030303534383135363562363030313630303036303030383238323534303139323530353038313930353535303562353630306131363536323761376137323330353832306436626365653661326333376165616364316439363438623461633630663239396561363333353062623136656135393930393237623861316461616132336430303239222c20226d756c74697369675f61646472657373223a20223347704750696f6648476f4d313953686a756e424e353367545341424c57685a5147222c2022636f6e74726163745f61646472657373223a202235303235313134643364646435336135363239373339663931376235653030373433636639373534227d",
            "asm":"OP_RETURN 7b22736f757263655f636f6465223a202236303630363034303532336636313030303035373562363030313630303038313930353535303562356236306238383036313030323236303030333936303030663330303630363036303430353236303030333537633031303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303039303034363366666666666666663136383036333031373235613062313436303436353738303633333731333033633031343630363635373562363030303536356233663630303035373630353036303732353635623630343035313830383238313532363032303031393135303530363034303531383039313033393066333562336636303030353736303730363037383536356230303562363030303534383135363562363030313630303036303030383238323534303139323530353038313930353535303562353630306131363536323761376137323330353832306436626365653661326333376165616364316439363438623461633630663239396561363333353062623136656135393930393237623861316461616132336430303239222c20226d756c74697369675f61646472657373223a20223347704750696f6648476f4d313953686a756e424e353367545341424c57685a5147222c2022636f6e74726163745f61646472657373223a202235303235313134643364646435336135363239373339663931376235653030373433636639373534227d"
         },
         "value":0,
         "n":1
      },
      {  
         "color":1,
         "scriptPubKey":{  
            "reqSigs":1,
            "type":"pubkeyhash",
            "hex":"76a91484c5d5e87df109be8d86b76f7dc84812799cefe088ac",
            "asm":"OP_DUP OP_HASH160 84c5d5e87df109be8d86b76f7dc84812799cefe0 OP_EQUALVERIFY OP_CHECKSIG",
            "addresses":[  
               "1D73CBMrBjPWdc133nn37VPetxR7Kmp2wA"
            ]
         },
         "value":999993200000000,
         "n":2
      }
   ],
   "time":1491361366,
   "blockhash":"0000048b9ac7d128cb8affcafde274cbf8e7f0b3d163945969648ad7184a62fb",
   "blocktime":1491361366
}
explorer
{  
   "hash":"38a3453bd218000492765d55b02b0b171c7a95adbfeaea92c6436b57a90841d0",
   "block_hash":"0000048b9ac7d128cb8affcafde274cbf8e7f0b3d163945969648ad7184a62fb",
   "version":"1",
   "locktime":"0",
   "type":"CONTRACT",
   "time":"1491361366",
   "confirmation":556,
   "vins":[  
      {  
         "tx_id":"4bcebb5628537c83c27f04a02e033b51aa61120bcb931f097d0496f21deae508",
         "vout":"2",
         "address":"1D73CBMrBjPWdc133nn37VPetxR7Kmp2wA",
         "color":1,
         "amount":"999993400000000",
         "scriptSig":"47304402205e017a9502c9ad98cc5ebf66e1cf2d18ca0c73afb542b51835d4afff0867dc3202207c325fd4b44799cd4a7254286b499818ba5c885a0e08c6b95c2a5ffc0e20c103012103b7516c9e4d6f2f2b74e0f5e5893d65ca239b3647d29496c95273bd000520d212",
         "sequence":"4294967295"
      }
   ],
   "vouts":[  
      {  
         "n":"0",
         "address":"3GpGPiofHGoM19ShjunBN53gTSABLWhZQG",
         "scriptPubKey":"a914a5e8e052333652edc0baa9d3926eb06af827eca687",
         "color":"1",
         "amount":"100000000"
      },
      {  
         "n":"1",
         "address":"",
         "scriptPubKey":"6a4d41027b22736f757263655f636f6465223a202236303630363034303532336636313030303035373562363030313630303038313930353535303562356236306238383036313030323236303030333936303030663330303630363036303430353236303030333537633031303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303039303034363366666666666666663136383036333031373235613062313436303436353738303633333731333033633031343630363635373562363030303536356233663630303035373630353036303732353635623630343035313830383238313532363032303031393135303530363034303531383039313033393066333562336636303030353736303730363037383536356230303562363030303534383135363562363030313630303036303030383238323534303139323530353038313930353535303562353630306131363536323761376137323330353832306436626365653661326333376165616364316439363438623461633630663239396561363333353062623136656135393930393237623861316461616132336430303239222c20226d756c74697369675f61646472657373223a20223347704750696f6648476f4d313953686a756e424e353367545341424c57685a5147222c2022636f6e74726163745f61646472657373223a202235303235313134643364646435336135363239373339663931376235653030373433636639373534227d",
         "color":"0",
         "amount":"0"
      },
      {  
         "n":"2",
         "address":"1D73CBMrBjPWdc133nn37VPetxR7Kmp2wA",
         "scriptPubKey":"76a91484c5d5e87df109be8d86b76f7dc84812799cefe088ac",
         "color":"1",
         "amount":"999993200000000"
      }
   ]
}

[CNT-144] OSS General Prepare Contract Type Support

The new smart contract architecture has two input addresses in function call transaction, so we need oss to support it.

OSS 這支 API 支援 op_return 且 type 為 contract
base/v1/general-transaction/prepare

交易範例
TX_ID

user_addr  amount(color) -> p2sh_addr1 amount(color)

                            p2sh_addr2 amount(color)

                            op_return amount(color) 

Implement `transaction API` and testing.

Two APIs to implement:

  • create raw transaction
  • send signed transaction

Before sending signed transaction, server should check the validity of the transaction.

[bug] POST license/send

環境:

  • core 1.2: gcoin-0-0.20170407git1103b55.el7.centos.src.rpm
  • oss: (master) 418aa88

測資:

core

root@core01 ~ $ gcoin-cli getmemberlist
{
    "member_list" : [
        "0220099eae73546d4817538c8f9a2436f8f9317611cf98ee7d738964db11bbc230",
        "0273ffaee25ec87373b5268771530cd3fa452123bd90dd52a0c6c5bc6fc838e554",
        "0371ce7c1ca4cb038f4614c9bd17a7b41c53fd54a730b578a6f375f31bff87aeff"
    ],
    "Consensus address for license" : "37dfubkrF5jfZkUgbXY1bwnQr3cJ48R153",
    "Consensus address for miner" : "37dfubkrF5jfZkUgbXY1bwnQr3cJ48R153"
}

oss

alliance_member_address:37dfubkrF5jfZkUgbXY1bwnQr3cJ48R153
color_id:6
name:vChain
description:vChain
member_control:false
metadata_link:http://example.com
to_address:1Pt3ukQgaJLLvVpCRikubTn6NcFL62KuNg

測試方法:

1 .
GET license/prepare
screenshot_at_apr_17_16-33-07

  • 反饋沒有 color 0, 於是在 core mintforlicense後,再試一次。
  • 如圖,記得修改錯誤信息的wording.
  • 反饋 raw_tx。
01000000013c21d77844f8190e0a1f870a99aaf56473bed81fe5c4a2f8ce8918c8122f91090000000017a914412ecc4eb612a3de590707ec0ee7a5b6cefa560987ffffffff0200e1f505000000001976a914fafa68f4cf68f4d9db7e714c32937182415da7de88ac070000000000000000000000d16a4cce3732313130313130303637363433363836313639366530363736343336383631363936653034366536663665363530313030303030303030303030303030303030303030303030303034366536663665363530303030303030303030303030303030303030303030303030303130363837343734373033613266326637363633363836313639366532653639366630303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030070000000000000030000000

使用 pygcointools signall_multisig(raw_tx,script,[priv1,priv2]) 對 raw_tx 簽名

使用 oss POST license/send 出錯。得到 invalid raw transaction
default

用 core sendrawtransaction 是 OK 的
screenshot at apr 17 17-08-53

raw_tx_signed

01000000013c21d77844f8190e0a1f870a99aaf56473bed81fe5c4a2f8ce8918c8122f910900000000fdfe0000483045022100fbaf32df7c571bd0cf93d253de41104a5949fd9e2dc505f4156bb27c87210c910220221697cc162c8ce4c0a3c60fb3502b8436d4b7f371a3fcf7acef7635b4ab497301483045022100e280ed16e1b33778e9dfe8b570867b3dbe6237d4ae4053f59d754c5236d0d15b02205db89823e1b24bac92938fee25093665e638548358082dbd605d5f28a4104104014c6952210220099eae73546d4817538c8f9a2436f8f9317611cf98ee7d738964db11bbc230210273ffaee25ec87373b5268771530cd3fa452123bd90dd52a0c6c5bc6fc838e554210371ce7c1ca4cb038f4614c9bd17a7b41c53fd54a730b578a6f375f31bff87aeff53aeffffffff0200e1f505000000001976a914fafa68f4cf68f4d9db7e714c32937182415da7de88ac070000000000000000000000d16a4cce3732313130313130303637363433363836313639366530363736343336383631363936653034366536663665363530313030303030303030303030303030303030303030303030303034366536663665363530303030303030303030303030303030303030303030303030303130363837343734373033613266326637363633363836313639366532653639366630303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030070000000000000030000000

Delete address subscription and then refer to the same subscription

前情提要

Smart Contract Event API 會在收到address notification 後,再送出 delete subscription 的要求:POST /notification/v1/address/subscription/[:subscription_id]/delete

錯誤發生

發現 addressnotify 會發生以下的錯誤訊息:

[root@oss oss_server]# python manage.py addressnotify
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/lib64/python2.7/site-packages/django/core/management/__init__.py", line 353, in execute_from_command_line
    utility.execute()
  File "/usr/lib64/python2.7/site-packages/django/core/management/__init__.py", line 345, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/lib64/python2.7/site-packages/django/core/management/base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/lib64/python2.7/site-packages/django/core/management/base.py", line 399, in execute
    output = self.handle(*args, **options)
  File "/root/OSS/oss_server/notification/management/commands/addressnotify.py", line 11, in handle
    daemon.run_forever()
  File "/root/OSS/oss_server/notification/daemon.py", line 220, in run_forever
    self.start_notify(notifications)
  File "/root/OSS/oss_server/notification/daemon.py", line 185, in start_notify
    'subscription_id': notification.subscription.id,
  File "/usr/lib64/python2.7/site-packages/django/db/models/fields/related_descriptors.py", line 169, in __get__
    rel_obj = qs.get()
  File "/usr/lib64/python2.7/site-packages/django/db/models/query.py", line 387, in get
    self.model._meta.object_name
notification.models.DoesNotExist: AddressSubscription matching query does not exist.

Trace

觀察程式碼有可能是在 OSS/oss_server/notification/daemon.py
還在跑for notification in notifications時,裡面會使用到 notification.subscription.id,但此subscription 已經被delete API 刪掉了

def start_notify(self, notifications):
        if notifications.count() == 0:
            return

        self.count = 0
        client = AsyncHTTPClient()
        headers = {'content-type': "application/x-www-form-urlencoded"}
        total = notifications.count()

        for notification in notifications:
            post_data = {
                'notification_id': notification.id,
                'subscription_id': notification.subscription.id,
                'tx_hash': notification.tx_hash,
            }
            request = HTTPRequest(
                          url=notification.subscription.callback_url,
                          headers=headers,
                          method='POST',
                          body=urllib.urlencode(post_data),
                          connect_timeout=180,
                          request_timeout=180
                      )

            client.fetch(request, self._get_callback_func(notification, total))

        # block until callback calls ioloop.IOLoop.instance().stop()
        ioloop.IOLoop.instance().start()

support gcoin core 1.2 transaction type

OSS
https://github.com/OpenNetworking/OSS/blob/core-1.2/oss_server/explorer/models.py#L101

class Tx(models.Model):
    TX_TYPE = {
        0: 'NORMAL',
        1: 'MINT',
        2: 'LICENSE',
        3: 'VOTE',
        4: 'BANVOTE',
        5: 'CONTRACT'
    }

gcoin core 1.2
https://github.com/OpenNetworking/gcoin/blob/opensource/src/primitives/transaction.h#L177

enum TransactionType
{
    // data
    NORMAL      =   0x00,
    MINT,
    CONTRACT    =   0x05,

    // permission relative type
    // Alliance
    VOTE        =   0x20,

    // Issuer
    LICENSE     =   0x30,

    // Miner
    MINER       =   0x40,
    DEMINER,

    UNKNOWN     =   0xff
};

假設使用者註冊認證信未收到或刪除,而無法或沒有擊連結完成註冊

假設使用者註冊認證信未收到或刪除,而無法或沒有擊連結完成註冊
會出現下列狀況
使用者無法重新註冊,輸入email會出現[提示]The email is already registered
使用者輸入帳號密碼後,會出現[提示]此帳號還未啟動
使用者無法點擊[忘記密碼],輸入email執行忘記密碼的動作,偶爾會出現畫面回傳{"type": "email"}
2b54f2f7ad8ee8103018affc166d348b

Support Bitocin

Because in base model, some api use rpc gettxoutaddress, which is not supported in Bitcoin.
So we need to implement those api in explorer model.

Smart Contract 端遇到 先被notify後,使用 explorer API 會查不到的時間差問題

Related issue: Smart Contract #202

Smart Contract 端會 subscribe txnotify 或 addressnotify,
收到 notification ,會使用explorer API 中的 /explorer/v1/transactions/address/{address} 檢查先前的 transaction,但此時可能還查不到最新的tx
先前 @icence 有想法是,是否可以在 OSS 端,改成設定「explorer有資料後再notification」?

deploy_contract 001

如上圖

  1. 因為有2.1 /notification/v1/tx/subscribe, 因此 OSS 會在 3.1 notify callback 給 oracle
  2. oracle 收到 tx 的 notification 後即再對 OSS 送出 4.1 /explorer/v1/transactions/address/{address},希望可以得到此address所有的交易資訊,用以在oracle端檢查此筆tx 前的相關合約操作都已經執行完成
  3. 但因為 4.1 /explorer/v1/transactions/address/{address} 是 explorer API ,在同步時間沒這麼快速的情況下,則有可能仍未包含最新的transaction 資訊!

Transaction Notification 增加確認次數之區塊時間

目前的 Transaction Notification Sample Request
https://github.com/OpenNetworking/OSS/wiki/Notification-module#transaction-notification

{
    "notification_id": "299f4f3f-71a7-4cb5-bb21-564e4c0f81bf",
    "subscription_id": "bd84e443-daa9-4000-a0ea-f162d273937a",
    "tx_hash": "e6372839ab539785191f9fcdb19e015ad0e72143709f14e50dc5f6d069dd888f",
}

訂閱方指定區塊確認次數及交易識別碼時,回傳訊息時提供使定區塊確認數及其區塊時間
預期呈現方式如下

{
    "notification_id": "299f4f3f-71a7-4cb5-bb21-564e4c0f81bf",
    "subscription_id": "bd84e443-daa9-4000-a0ea-f162d273937a",
    "tx_hash": "e6372839ab539785191f9fcdb19e015ad0e72143709f14e50dc5f6d069dd888f",
    "confirmation": "2"
    "confirmation_time": "<unix timestamp>",
}

在應用場景中遇到callback_url固定是同一訊息接收端,同時接收區塊確認次數2及3的通知,原因是其將次數1判斷為"交易確認中",次數2判斷"交易已完成"

/license/send 癱瘓

prepare完新的license,要透過oss來send就會timeout
推測是gcoin-cli掛點

/explorer/v1/blocks 分頁無法翻回前頁問題

需求功能如下:
pagination

因為blocks API回傳的資料中 不包含starting_after的block hash資料

造成無法翻回第一頁,因為永遠不知道最新的block的下一個block hash

故無法組出prev_uri功能加在原本的page json資料區塊中

同理,透過date picker選擇某一天的block列表也要能往前往後翻頁

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.