Coder Social home page Coder Social logo

corda-solutions's Introduction

corda-solutions's People

Contributors

aelahi23 avatar alex-koller-r3 avatar alicer3 avatar amolpednekar avatar amoothart avatar andreaborzi avatar clintonio avatar guyho avatar henrikr3 avatar ischasny avatar jorpic avatar mattbradburyuk avatar mcevoyinit avatar mplatt avatar mplattr3 avatar mrmatthewlayton avatar roastario avatar simonr3 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

Watchers

 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

corda-solutions's Issues

Multiple Business Networks

With version 3.0, you introduced the "networkId" as a parameter to many flows, letting us believe we can handle multiple networks. But something is still unclear to me:

How many membership-service.conf files should we have? In my opinion, if we want to enable multiple networks, we should be able to have multiple configuration files, one for each network.

However, this doesn't seem to be the case, especially when I read the README in membership-management/.

So either the doc still hasn't been fully updated, or I am missing something. Can you please shed some light on my dilemma? Thank you in advance.

Update site

From customer feedback:

Hello Gowry,
Here are some things:
• On the top left corner, it's written 2018.
• Much of the documentation is still mentioning Corda 3.2. (e.g.: Theon-premise pre-requisites https://solutions.corda.net/deployment/prerequisites-sizing.html)
• The documentation has not really been updated recently: https://github.com/corda/corda-solutions/tree/master/docs/source
Since it's linked to a team, I assume that it's supported to be somehow maintained.
Thanks,
Julien

In addition we should add versions to match the corda version.

Use custom linearId as a parameter when invoking 'IssueBillingStateFlow'

Issue
The BillingState linearId can be overriden on the state class, in our use case we want to be able to assign our own custom linearId by overriding this property whilst at the same time leveraging the Corda Billing SDK as much as possible. Currently the IssueBillingStateFlowlibrary flow does not support passing in a custom UniqueIdentifier as a parameter to be used instead of generating one after invocation.

Current implementation:
IssueBillingStateFlow public constructor(owner: Party, amount: Long, expiryDate: Instant? ...)

Proposed:
IssueBillingStateFlow public constructor(owner: Party, amount: Long, expiryDate: Instant?, id: UniqueIdentifier? ...)

This optional parameter id would then be used to override the linearId property of the billing state within the IssueBillingStateFlow.

Link to flow in question: https://github.com/corda/corda-solutions/blob/master/bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/bno/IssueBillingStateFlow.kt

Billing Problem with Leaking Billing State amongst participants on a transaction

Some good work was done into not leaking transaction history but one could argue that the billing states themselves should only be viewed by the owner of the billing state. By adding the billing states as reference states to the transaction to do expiry checks etc. we end up leaking the billing states to all of the parties in the transaction. So all the parties would know my expiry date, amount and how much I have spent; not sure it is a huge deal but something to be aware of.

SelfIssueMembershipFlow is not available in 2.0

The README instructs for v2.0 dependencies, but those do not see m to contain SelfIssueMembershipFlow as documented in the same document. Is there any version available where the BNO can self-issue it's own membership? Even the 3.0-SNAPSHOT I just pulled in doesn't contain SelfIssueMembershipFlow.

Furthermore, for project that need a non-SNAPSHOT release for a release of their own, will there be a regular release with SelfIssueMembershipFlow soon-ish?

Billing Problem with Non BNO issuing billing states

With regards to the billing service,

There is nothing preventing peers on the network from issuing each other billing states that work fine in any of the transactions requiring billing chips. The only node that should be able to issue billing states is the BNO. Offhand, I am not sure of the best way to solve this.
However it does seem to have checks to prevent issuing yourself a billing state.

Master build fails

It appears com.r3:vr-db-service is not publicly accessible:

manos@tower:~/git/corda-solutions$ ./gradlew build
> Task :bn-apps:ledger-sync:ledger-sync-service:compileTestKotlin FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':bn-apps:ledger-sync:ledger-sync-service:compileTestKotlin'.
> Could not resolve all files for configuration ':bn-apps:ledger-sync:ledger-sync-service:testCompileClasspath'.
   > Could not resolve com.r3:vr-db-service:2.0-20190716.190016-1.
     Required by:
         project :bn-apps:ledger-sync:ledger-sync-service
      > Could not resolve com.r3:vr-db-service:2.0-20190716.190016-1.
         > Could not get resource 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-solutions-private-dev/com/r3/vr-db-service/2.0-SNAPSHOT/vr-db-service-2.0-20190716.190016-1.pom'.
            > java.lang.NullPointerException (no error message)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/4.10.3/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 5s
72 actionable tasks: 9 executed, 63 up-to-date
manos@tower:~/git/corda-solutions$ 

Compatibility with CordappContext.config

ConfigurationService and ConfigUtils should use CordappContext.config as described in CorDapp configuration files, or at least provide compatibility with the convention.

The current implementation is incompatible with cordapp configuration hooks available, e.g. in the Cordform gradle task, or the TestCordapp.withConfig used with MockNetwork.

Even a minimal change such as updating the target file names according to the convention might just work, e.g. "membership-service-2.0.conf" VS "membership-service.conf"

AmendMembershipMetadataFlow RPC annotation

Why is it that the flow AmendMembershipMetadataFlow is not startable by RPC. Is there a particular reason for it?

open class AmendMembershipMetadataFlow(bno: Party, private val newMetadata: Any, private val networkID: String?) : BusinessNetworkAwareInitiatingFlow<SignedTransaction>(bno) {

IssueBillingStateFlow fails when called over RPC

I am trying to issue a BillingState using the following command over RPC, using the Corda-kotlin-shell:

val handle = bnoproxy.startFlowDynamic(IssueBillingStateFlow::class.java, aparty, 100L)

(where aparty is a Party on the Network)

The Corda-kotlin-shell returns this error:
net.corda.nodeapi.exceptions.InternalNodeException: Something went wrong within the Corda node.

The bno node has this in the logs:

[ERROR] 2019-08-12T12:45:20,053Z [rpc-server-handler-pool-1] proxies.ExceptionMaskingRpcOpsProxy.log - Error during RPC invocation [errorCode=1p7l4gs, moreInformationAt=https://errors.corda.net/OS/4.0/1p7l4gs] {actor_id=user1, actor_owning_identity=O=BNO, L=London, C=GB, actor_store_id=NODE_CONFIG, invocation_id=59934bef-81c6-4344-8668-ac9de619037e, invocation_timestamp=2019-08-12T12:45:20.043Z, origin=user1, session_id=5bf95075-a0c8-4f70-8883-a712b9f10292, session_timestamp=2019-08-12T12:43:26.526Z}
net.corda.core.flows.IllegalFlowLogicException: A FlowLogicRef cannot be constructed for FlowLogic of type com.r3.businessnetworks.billing.flows.bno.IssueBillingStateFlow: due to missing constructor for arguments: [class net.corda.core.identity.Party, class java.lang.Long]
at net.corda.node.services.statemachine.FlowLogicRefFactoryImpl.createForRPC(FlowLogicRefFactoryImpl.kt:80) ~[corda-node-4.0.jar:?]
at net.corda.node.internal.FlowStarterImpl.invokeFlowAsync(AbstractNode.kt:1054) ~[corda-node-4.0.jar:?]
at net.corda.node.internal.CordaRPCOpsImpl.startFlow(CordaRPCOpsImpl.kt:197) ~[corda-node-4.0.jar:?]
at net.corda.node.internal.CordaRPCOpsImpl.startFlowDynamic(CordaRPCOpsImpl.kt:188) ~[corda-node-4.0.jar:?]
at net.corda.node.internal.rpc.proxies.AuthenticatedRpcOpsProxy$startFlowDynamic$2.invoke(AuthenticatedRpcOpsProxy.kt:26) ~[corda-node-4.0.jar:?]
at net.corda.node.internal.rpc.proxies.AuthenticatedRpcOpsProxy$startFlowDynamic$2.invoke(AuthenticatedRpcOpsProxy.kt:15) ~[corda-node-4.0.jar:?]
at net.corda.node.internal.rpc.proxies.AuthenticatedRpcOpsProxyKt.guard(AuthenticatedRpcOpsProxy.kt:52) ~[corda-node-4.0.jar:?]
at net.corda.node.internal.rpc.proxies.AuthenticatedRpcOpsProxyKt.access$guard(AuthenticatedRpcOpsProxy.kt:1) ~[corda-node-4.0.jar:?]
at net.corda.node.internal.rpc.proxies.AuthenticatedRpcOpsProxy.startFlowDynamic(AuthenticatedRpcOpsProxy.kt:25) ~[corda-node-4.0.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_192]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_192]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_192]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_192]
at net.corda.node.internal.InvocationHandlerTemplate$DefaultImpls.invoke(InvocationHandlerTemplate.kt:16) ~[corda-node-4.0.jar:?]
at net.corda.node.internal.rpc.proxies.ExceptionMaskingRpcOpsProxy$ErrorObfuscatingInvocationHandler.invoke(ExceptionMaskingRpcOpsProxy.kt:46) ~[corda-node-4.0.jar:?]
at com.sun.proxy.$Proxy35.startFlowDynamic(Unknown Source) ~[?:?]
at net.corda.node.internal.rpc.proxies.ExceptionMaskingRpcOpsProxy.startFlowDynamic(ExceptionMaskingRpcOpsProxy.kt) ~[corda-node-4.0.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_192]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_192]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_192]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_192]
at net.corda.node.internal.InvocationHandlerTemplate$DefaultImpls.invoke(InvocationHandlerTemplate.kt:16) ~[corda-node-4.0.jar:?]
at net.corda.node.internal.rpc.proxies.ExceptionSerialisingRpcOpsProxy$ErrorSerialisingInvocationHandler.invoke(ExceptionSerialisingRpcOpsProxy.kt:36) ~[corda-node-4.0.jar:?]
at com.sun.proxy.$Proxy35.startFlowDynamic(Unknown Source) ~[?:?]
at net.corda.node.internal.rpc.proxies.ExceptionSerialisingRpcOpsProxy.startFlowDynamic(ExceptionSerialisingRpcOpsProxy.kt) ~[corda-node-4.0.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_192]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_192]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_192]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_192]
at net.corda.node.internal.InvocationHandlerTemplate$DefaultImpls.invoke(InvocationHandlerTemplate.kt:16) ~[corda-node-4.0.jar:?]
at net.corda.node.internal.rpc.proxies.ThreadContextAdjustingRpcOpsProxy$ThreadContextAdjustingInvocationHandler$invoke$1.invoke(ThreadContextAdjustingRpcOpsProxy.kt:25) ~[corda-node-4.0.jar:?]
at net.corda.core.internal.ClassLoadingUtilsKt.executeWithThreadContextClassLoader(ClassLoadingUtils.kt:36) ~[corda-core-4.0.jar:?]
at net.corda.node.internal.rpc.proxies.ThreadContextAdjustingRpcOpsProxy$ThreadContextAdjustingInvocationHandler.invoke(ThreadContextAdjustingRpcOpsProxy.kt:25) ~[corda-node-4.0.jar:?]
at com.sun.proxy.$Proxy35.startFlowDynamic(Unknown Source) ~[?:?]
at net.corda.node.internal.rpc.proxies.ThreadContextAdjustingRpcOpsProxy.startFlowDynamic(ThreadContextAdjustingRpcOpsProxy.kt) ~[corda-node-4.0.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_192]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_192]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_192]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_192]
at net.corda.node.services.rpc.RPCServer.invokeRpc(RPCServer.kt:360) ~[corda-node-4.0.jar:?]
at net.corda.node.services.rpc.RPCServer.access$invokeRpc(RPCServer.kt:77) ~[corda-node-4.0.jar:?]
at net.corda.node.services.rpc.RPCServer$clientArtemisMessageHandler$4.run(RPCServer.kt:333) ~[corda-node-4.0.jar:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_192]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_192]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[?:1.8.0_192]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[?:1.8.0_192]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_192]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_192]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_192]

The source code for the class is:

@StartableByRPC
@InitiatingFlow
class IssueBillingStateFlow(private val owner : Party,
private val amount : Long,
private val expiryDate : Instant? = null,
private val category : String? = null) : FlowLogic<Pair<BillingState, SignedTransaction>>()

I believe the constructor is correct, because when I create the IssueBillingStateFlow in the Corda-kotlin-shell, it creates it correctly:

val ibsf = IssueBillingStateFlow(aparty, 100L)
ibsf
com.r3.businessnetworks.billing.flows.bno.IssueBillingStateFlow@7c9afc5c
getClass(ibsf)
class com.r3.businessnetworks.billing.flows.bno.IssueBillingStateFlow

Extension of the fields mapped for MembershipState

In the MembershipState data class, in the generateMappedObject function, why doesn't it map all of the fields?
Why does it only map member, bno and status?
It would be useful to also map the rest of the fields, especially membershipMetadata. But because it currently extends Any, I understand this would be a problem, but by giving it a base class (like the SimpleMembershipMetadata), it could map some of its fields as well.

how to handle a use-case where a node is sharing multiple BNO

How do we handle a scenario when a node in CZ needs to access two different BN.
From my understanding ,I can see the following ways

  1. We could have different membership cordapp with different BNO name configuration
    I mean this node will have cordapps 1. two membership cordapp with different BNO configured
  2. how will the notary will be configured in this scenario ?
    I am thinking that if we have common notary then different BNs will share the txn in this case

These are my assumptions

URI is not hierarchical exception from MemberConfigurationService while building the project

I think we should use ResourceAsStream here because of the membership-service.conf exist inside the Jar, while gradlew build starting the test cases.

Caused by: java.lang.IllegalArgumentException: URI is not hierarchical
	at java.io.File.<init>(File.java:418) ~[?:1.8.0_171]
	at com.r3.businessnetworks.membership.flows.ConfigUtils.loadConfig(ConfigUtils.kt:16) ~[membership-service-2.0.jar:?]
	at com.r3.businessnetworks.membership.flows.member.service.MemberConfigurationService.<init>(MemberConfigurationService.kt:25) ~[membership-service-2.0.jar:?]

else ConfigFactory.parseFile(File(ConfigUtils::class.java.classLoader.getResource(propertiesFileName).toURI()))

In release 2.0 three tests in com.r3.businessnetworks.cordaupdates.transport.MavenOverFlowsTests fail

In release 2.0 three tests in com.r3.businessnetworks.cordaupdates.transport.MavenOverFlowsTests fail.v

Task :bn-apps:cordapp-updates-distribution:corda-updates-transport:test

com.r3.businessnetworks.cordaupdates.transport.MavenOverFlowsTests > repository name should be set to default if not explicitly provided FAILED
java.lang.AssertionError at MavenOverFlowsTests.kt:44

com.r3.businessnetworks.cordaupdates.transport.MavenOverFlowsTests > Should download the version range from the specified repository FAILED
java.lang.AssertionError at MavenOverFlowsTests.kt:44

com.r3.businessnetworks.cordaupdates.transport.MavenOverFlowsTests > Should fetch artifacts from the specified repository FAILED
java.lang.AssertionError at MavenOverFlowsTests.kt:44

16 tests completed, 3 failed

Task :bn-apps:cordapp-updates-distribution:corda-updates-transport:test FAILED

FAILURE: Build failed with an exception.

Steps to reproduce:

  1. git pull https://github.com/corda/corda-solutions.git releases/2.0
  2. ./gradlew clean test

membership cordapp doesn't run on Corda Enterprise 4.1

I suspect because it's missing liquibase migration scripts:

[ERROR] 2019-07-10T15:10:12,661Z [main] internal.NodeStartupLogging.invoke - Could not create the DataSource: No migration defined for schema: com.r3.businessnetworks.membership.flows.bno.service.PendingMembershipRequestSchema v1: Could not create the DataSource: No migration defined for schema: com.r3.businessnetworks.membership.flows.bno.service.PendingMembershipRequestSchema v1 [errorCode=5k06pt, moreInformationAt=https://errors.corda.net/ENT/4.1/5k06pt] {}
net.corda.nodeapi.internal.persistence.CouldNotCreateDataSourceException: Could not create the DataSource: No migration defined for schema: com.r3.businessnetworks.membership.flows.bno.service.PendingMembershipRequestSchema v1
        at net.corda.node.internal.AbstractNodeKt.startHikariPool(AbstractNode.kt:1181) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.AbstractNode.startDatabase(AbstractNode.kt:830) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.Node.startDatabase(Node.kt:465) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.AbstractNode.start(AbstractNode.kt:345) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.Node.start(Node.kt:480) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.EnterpriseNode.start(EnterpriseNode.kt:189) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.NodeStartup.startNode(NodeStartup.kt:190) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.NodeStartupCli$runProgram$2.run(NodeStartup.kt:113) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.NodeStartup$initialiseAndRun$5.invoke(NodeStartup.kt:167) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.NodeStartup$initialiseAndRun$5.invoke(NodeStartup.kt:120) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.NodeStartupLogging$DefaultImpls.attempt(NodeStartup.kt:498) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.NodeStartup.attempt(NodeStartup.kt:120) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.NodeStartup.initialiseAndRun(NodeStartup.kt:166) ~[corda-node-4.1.jar:?]
        at net.corda.node.internal.NodeStartupCli.runProgram(NodeStartup.kt:111) ~[corda-node-4.1.jar:?]
        at net.corda.cliutils.CordaCliWrapper.call(CordaCliWrapper.kt:190) ~[corda-tools-cliutils-4.1.jar:?]
        at net.corda.cliutils.CordaCliWrapper.call(CordaCliWrapper.kt:156) ~[corda-tools-cliutils-4.1.jar:?]
        at picocli.CommandLine.execute(CommandLine.java:1056) ~[picocli-3.8.0.jar:3.8.0]
        at picocli.CommandLine.access$900(CommandLine.java:142) ~[picocli-3.8.0.jar:3.8.0]
        at picocli.CommandLine$RunLast.handle(CommandLine.java:1246) ~[picocli-3.8.0.jar:3.8.0]
        at picocli.CommandLine$RunLast.handle(CommandLine.java:1214) ~[picocli-3.8.0.jar:3.8.0]
        at picocli.CommandLine$AbstractParseResultHandler.handleParseResult(CommandLine.java:1122) ~[picocli-3.8.0.jar:3.8.0]
        at picocli.CommandLine.parseWithHandlers(CommandLine.java:1405) ~[picocli-3.8.0.jar:3.8.0]
        at net.corda.cliutils.CordaCliWrapperKt.start(CordaCliWrapper.kt:73) ~[corda-tools-cliutils-4.1.jar:?]
        at net.corda.node.Corda.main(Corda.kt:13) ~[corda-node-4.1.jar:?]
Caused by: net.corda.nodeapi.internal.persistence.MissingMigrationException: No migration defined for schema: com.r3.businessnetworks.membership.flows.bno.service.PendingMembershipRequestSchema v1
        at net.corda.nodeapi.internal.persistence.SchemaMigration.doRunMigration(SchemaMigration.kt:137) ~[corda-node-api-4.1.jar:?]
        at net.corda.nodeapi.internal.persistence.SchemaMigration.runMigration(SchemaMigration.kt:79) ~[corda-node-api-4.1.jar:?]
        at net.corda.nodeapi.internal.persistence.SchemaMigration.runMigration$default(SchemaMigration.kt:79) ~[corda-node-api-4.1.jar:?]
        at net.corda.nodeapi.internal.persistence.SchemaMigration.nodeStartup(SchemaMigration.kt:68) ~[corda-node-api-4.1.jar:?]
        at net.corda.node.internal.AbstractNodeKt.startHikariPool(AbstractNode.kt:1173) ~[corda-node-4.1.jar:?]
        ... 23 more

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.