Git Product home page Git Product logo

xdk_on_ethereum's Introduction

EthereumOnXDK (EOX)

This is the companion code for Connecting XDKs to Ethereum Network. The code allows the users to set up CoAP communication between two XDKs and to execute a SmartContract running on Ethereum Nodes.
It enables RSA secured data exchange against payment between two Bosch XDK's over the Ethereum Blockchain node.

Purpose of the project

This software is a research prototype, solely developed for and published as part of the publication of XDK example codes. It will neither be maintained nor monitored in any way.

License

The software and documentation is released under the MIT license. See the LICENSE file for details. For a list of other open source components included in EOX, see the file 3rd-party-licenses.txt.

Requirements, how to build, test, install, use, etc.

The program was written with XDK workbench release version 3.3.1.

To get it running you also need an Ethereum Blockchain setup which includes at least two nodes with unlocked accounts, JSON-RPC open and mining enabled (for a local setup, I recommend using Truffle and Ganache (Version 1.2.0 is used here)).

Step by step instructions:

  1. Get the source code
  2. Import the project into the XDK workbench with the import wizard (existing code as makefile project). Choose BCDS XDK Toolchain for indexer settings.
  3. Adapt common XDK makefiles as described in the HowToMbedTLS folder
  4. Adapt UserConfig.h header file to your needs. Wi-Fi credentials and Ethereum blockchain information (Contract address, Producer/Consumer account address) has to be adapted.
  5. Increase ServalPal stack size to 1024 Bytes #define TASK_STACK_SIZE_SERVALPAL_CMD_PROC UINT32_C(1024) in file SDK\xdk110\Common\legacy\source\ServalPAL_WiFi.c.
  6. Clean, Build and flash the project for Producer and Consumer. Producer and Consumer build can be started via the build variables ENABLE_PRODUCER/ENABLE_CONSUMER in UserConfig.h file.

To build the Producer you have to enable the #define ENABLE_PRODUCER macro in source\UserConfig.h and disable #define ENABLE_CONSUMER.

To build the Consumer you have to enable the #define ENABLE_CONSUMER macro in source\UserConfig.h and disable #define ENABLE_PRODUCER.

Note: If your blockchain uses other account/contract addresses, then you have to adapt those in the source code in the UserConfig.h file. If you want to use a WIFI enterprise network, you have to update the WIFI chip. A HowTo can be found in the Bosch XDK community (https://xdk.bosch-connectivity.com/community/-/message_boards/message/260455).

Important: Increase ServalPal stack size to 1024 Bytes #define TASK_STACK_SIZE_SERVALPAL_CMD_PROC UINT32_C(1024) in file xdk110\Common\legacy\source\ServalPAL_WiFi.c.

  • debug_Consumer/Producer folders contain the Consumer and Producer debug binaries.
  • HowToMbedTLS folder contains a HowTo for compiling and including the mbedTLS library in the Bosch XDK project. It also contains two configuration makefiles which can be used as a template.
  • mbedtls folder contains the compiled mbedtls libraries as well as the include files.
  • RSA_1024_Bit_Keypairs contains the generated private/public key pairs as .pem files.
  • SmartContract folder contains the Ethereum smart contract implemented in solidity.
  • Source folder contains the XDK application code.
  • SED_ConsoleOutput.txt shows the console output of one communication cycle between Producer and Consumer.

Use-Case

Short version

  • One edge device called Producer (Bosch XDK1) collects and sells acceleration data during a given period of time. The second edge device called Consumer (Bosch XDK2) is willing to buy this acceleration data from the Producer.
  • The Producer provides a smart contract running on the Ethereum blockchain to provide data integrity, a secure payment channel, an incentive-based evaluation system and RSA key exchange along with Consumer authentication.
  • Off-chain data is encrypted via the RSA algorithm and is directly exchanged over the CoAP protocol between Producer and Consumer.
  • On-chain communication between the XDKs and the Ethereum node RPC server is done via the http protocol.
  • The XDK implementation as well as the smart contract implementation are limited to two communication partners at a time.

Long version

Two constraint embedded devices securely exchange encrypted sensor data against a payment. One edge device called Producer (Bosch XDK1) collects acceleration data during a given period of time. The second edge device called Consumer (Bosch XDK2) is willing to buy this acceler-ation data from the Producer.

The two parties go through five successive phases. Starting with a Registration phase, continue through a Search and Enquiry phase, to a Settlement and finally a Post-Settlement phase. On the Producer and Consumer side, the RSA keypair is stored in local buffers to enable encrypted off-chain communication. For now, those keys are generated offline once and then stored on the XDK. The remote nodes which are used for on-chain communication are registered to the blockchain in the Registration phase. Here, the Producer communicates via Node1 whereas the Consumer communicates via Node2 with the blockchain network. After this, the unlocked Producer/Consumer Ethereum accounts with a unique address as well as the XDKs are setup for on-/off-chain communication. This registration process only takes place once at the beginning. For testing purposes, this means a private Ethereum blockchain setup, including two nodes with at least one unlocked account on each node with mining enabled is required.

The smart contract is deployed to the blockchain through Node1 which represents the Producer account. As a result, the smart contract gets stored on the distributed ledger with his own unique Ethereum address. The contract sets the creator account as the smart contract owner. Everyone participating in the network can interact with the contract through the generated address, but some contract functions are access restricted to the contract owner. Node2 is now able to find the contract if it knows the address in advance. An automatic search function to somehow find the contract address without knowing the address in advance is not supported. The Registration and Search phases are used to setup the entire communication environment.

As mentioned previously, the Consumer must know the contract address to interact with it. For this, the first step of the Enquiry phase is to provide the contract address to the Consumer. As the Producer is the contract owner, he provides this information directly through the off-chain communication channel. After the contract address is received, the Consumer pushes his RSA public key along with a pre-payment through Node2 into the smart contract. Node2 is responsible to prepare and forward the json-rpc message to the distributed ledger network. This requires a specific hash and sign procedure with the Ethereum account keypair. The public key, the payment and the corresponding Consumer account address are stored in the smart contract. So, the contract stores a current state of the Consumer, including his payed amount of ether and the associated public key.

After the Consumer receives a transaction confirmation from the blockchain, he requests sensor data directly from the Producer. The Producer reads the provided information out of the contract and is now able to encrypt data locally with the Consumer public key from the blockchain. Furthermore, the Producer also stores the associated unique Ethereum account address and is therefore able to authenticate the Consumer. With this information locally available at the Producer, it removes the need to rewrite the Consumers RSA public key into the blockchain during a later communication cycle. This means, after the public key is written once, the authenticated Consumer can now directly communicate with the Producer. So, the Consumer pays only once during the write public key transaction for the data until the Producer decides to delete the locally stored Consumer information.

To provide data integrity, the Producer calculates the hash of the encrypted data. The hash value gets written into the smart contract through Node1, which is again responsible to process and forward the json-rpc message of the Producer to the ledger network.

Finally, the Producer sends the encrypted acceleration sensor data off-chain to the Consumer. Because only the Consumer owns and knows the private RSA key, only he can decrypt the received sensor data. To verify the received data, the Consumer reads the data hash out of the smart contract and compares it with his self-calculated data hash. If something went wrong during transaction or if anyone manipulated the data, the Consumer can immediately detect the tampered data.

Along with the RSA public key write operation, the Consumer must provide a specified amount of ether as a pre-payment. During the write operation, the smart contract checks if enough ether is sent along the transaction. If this is the case, the pre-payment gets stored in the smart contract along with the public key. This payment is now only accessible by the smart contract on the blockchain, which means neither the Producer nor the Consumer owns it. The Settlement phase is executed in parallel to the Enquiry phase but is only executed if the right amount of ether is sent along with the write public key transaction.

Finally, the Post-settlement phase is executed after the encrypted sensor data has been exchanged and verified. After the Consumer has verified the received sensor data based on the data hash from the blockchain, as a final step he evaluates the transaction with the Producer. A positive or a negative evaluation option is available. Only a Consumer who previously made a payment is allowed to vote. The Producer itself is also excluded from the voting procedure.

This evaluation system provides incentive for the Producer and the Consumer to act “fair” during the entire process. It automatically releases the pre-payment of the Settlement phase to the Producer Node1 if the evaluation result is positive and refunds the Consumer Node2 with half of his initial payment. If the evaluation result is negative, the Consumer as well as the Producer don’t receive any funds from the smart contract.

Furthermore, other Consumers can read the current Producer rating out of the smart contract as a percentage value. This gives the Producer one more incentive to provide unaltered and correct data.

HowTo use the implemented demonstrator

  1. Press button1 on XDK1 (Producer) to record accelerometer data before communication
    • XDK1 calculates the acceleration data during the first 1000 ticks after button pressed on XDK1
    • Yellow LED of XDK1 lights up if acceleration data < 5g, red if accel-data > 5g
  2. By clicking button1 on XDK2 (Consumer), it asks XDK1 about the smart contract address
  3. XDK1 sends the SC address
  4. XDK2 writes pubKey2 to SC, SC stores address of XDK2 along with pubKey2
  5. By clicking button1 on XDK2, it initializes the acceleration sensor data preparation
  6. XDK1 reads pubKey2 and prepares the sensor data
  7. By clicking button1 on XDK2, it requests acceleration data of XDK1
  8. If data processing is finished, XDK1 sends the encrypted sensor data
  9. Yellow LED of XDK2 lights up if received accel-data < 5g, red if accel-data > 5g
  10. XDK2 sends evaluation voting to SC

xdk_on_ethereum's People

Contributors

lamecat-yang avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

mishaaaa

xdk_on_ethereum's Issues

Problem building...

I am getting this error when I try to build this project...
https://github.com/boschresearch/XDK_on_Ethereum

mingw32-make[2]: Leaving directory 'C:/XDK-Workbench/XDK/SDK/xdk110/Libraries/FATfs'
Build 3rd-party/ServalStack/src/Http/OverloadHandling.c
Building file source/ExtensionPortSpi.c
C:\XDK-Workbench\XDK\armGCC\bin/arm-none-eabi-gcc -MMD -MP -MF C:/XDK_on_Ethereum-master/debug/objects/source/ExtensionPortSpi.d -std=c99 -Wall -Wextra -Wstrict-prototypes -D EFM32GG390F1024 -D BCDS_TARGET_EFM32 -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections -D SERVAL_LOG_LEVEL=SERVAL_LOG_LEVEL_ERROR -D SERVAL_ENABLE_HTTP_CLIENT=1 -D SERVAL_ENABLE_HTTP_SERVER=1 -D SERVAL_ENABLE_WEBSERVER=1 -D SERVAL_ENABLE_COAP_OBSERVE=1 -D SERVAL_ENABLE_COAP_CLIENT=1 -D SERVAL_ENABLE_COAP_SERVER=1 -D SERVAL_ENABLE_REST_CLIENT=1 -D SERVAL_ENABLE_REST_SERVER=1 -D SERVAL_ENABLE_REST_HTTP_BINDING=1 -D SERVAL_ENABLE_REST_COAP_BINDING=1 -D SERVAL_ENABLE_XUDP=1 -D SERVAL_ENABLE_DPWS=0 -D SERVAL_ENABLE_TLS_CLIENT=0 -D SERVAL_ENABLE_TLS_SERVER=0 -D SERVAL_ENABLE_TLS_ECC=0 -D SERVAL_ENABLE_TLS_PSK=0 -D SERVAL_ENABLE_DTLS=0 -D SERVAL_ENABLE_DTLS_CLIENT=0 -D SERVAL_ENABLE_DTLS_SERVER=0 -D SERVAL_ENABLE_DTLS_PSK=0 -D SERVAL_ENABLE_HTTP_AUTH=1 -D SERVAL_ENABLE_HTTP_AUTH_DIGEST=1 -D SERVAL_ENABLE_DUTY_CYCLING=1 -D SERVAL_ENABLE_APP_DATA_ACCESS=0 -D SERVAL_ENABLE_COAP_COMBINED_SERVER_AND_CLIENT=0 -D SERVAL_ENABLE_COAP_OBSERVE=1 -D SERVAL_ENABLE_LWM2M=1 -D SERVAL_ENABLE_XTCP=1 -D SERVAL_ENABLE_XTCP_SERVER=1 -D SERVAL_ENABLE_XTCP_CLIENT=1 -D SERVAL_HTTP_MAX_NUM_SESSIONS=3 -D SERVAL_HTTP_SESSION_MONITOR_TIMEOUT=4000 -D SERVAL_MAX_NUM_MESSAGES=16 -D SERVAL_MAX_SIZE_APP_PACKET=600 -D SERVAL_MAX_SECURE_SOCKETS=5 -D SERVAL_MAX_SECURE_CONNECTIONS=5 -D SERVAL_SECURE_SERVER_CONNECTION_TIMEOUT=300000 -D SERVAL_DOWNGRADE_TLS=1 -D SERVAL_ENABLE_DTLS_ECC=0 -D SERVAL_ENABLE_DTLS_RSA=0 -D COAP_MSG_MAX_LEN=224 -D COAP_MAX_NUM_OBSERVATIONS=50 -D LWM2M_MAX_NUM_OBSERVATIONS=50 -D SERVAL_LWM2M_SECURITY_INFO_MAX_LENGTH=65 -D LWM2M_IP_ADDRESS_MAX_LENGTH=65 -D SERVAL_HTTP_MAX_LENGTH_URL=256 -D SERVAL_TLS_MBEDTLS=0 -D LWM2M_MAX_LENGTH_DEVICE_NAME=32 -D SERVAL_ENABLE_DTLS_SESSION_ID=0 -D LWM2M_DISABLE_CLIENT_QUEUEMODE=1 -D PAL_MAX_NUM_ADDITIONAL_COMM_BUFFERS=6 -D SERVAL_ENABLE_DTLS_HEADER_LOGGING=0 -D SERVAL_DTLS_FLIGHT_MAX_RETRIES=4 -D SERVAL_EXPERIMENTAL_DTLS_MONITOR_EXTERN=0 -D SERVAL_POLICY_STACK_CALLS_TLS_API=1 -D SERVAL_SECURITY_API_VERSION=2 -D SERVAL_ENABLE_HTTP_RANGE_HANDLING=1 -D SERVAL_ENABLE_MQTT=1 -D SERVAL_ENABLE_TLS=0 -D COAP_OVERLOAD_QUEUE_SIZE=15 -D SERVAL_ENABLE_SNTP_CLIENT=1 -D SERVAL_ENABLE_HTTP=1 -D BCDS_SERVAL_COMMBUFF_SEND_BUFFER_MAX_LEN=1000 -D SERVAL_XML_PARSER=1 -D XDK_MBEDTLS_PARSE_INFO=0 -D DEFAULT_STARTUP -D XDK_CONNECTIVITY_BLE=1 -D XDK_CONNECTIVITY_HTTPRESTCLIENT=1 -D XDK_CONNECTIVITY_LED=1 -D XDK_CONNECTIVITY_LORA=1 -D XDK_CONNECTIVITY_LWM2M=1 -D XDK_CONNECTIVITY_MQTT=1 -D XDK_CONNECTIVITY_UDP=1 -D XDK_CONNECTIVITY_WLAN=1 -D XDK_SENSOR_SENSOR=1 -D XDK_SENSOR_BUTTON=1 -D XDK_SENSOR_EXTERNALSENSOR=1 -D XDK_SENSOR_VIRTUALSENSOR=1 -D XDK_UTILITY_SERVALPAL=1 -D XDK_UTILITY_STORAGE=1 -D XDK_UTILITY_SNTP=1 -D ENABLE_DMA -D ARM_MATH_CM3 -D XDK_FOTA_ENABLED_BOOTLOADER=1 -D BCDS_SERVALPAL_WIFI=1 -D BCDS_EMLIB_INCLUDE_USB=1 -D BCDS_FREERTOS_INCLUDE_AWS=0 -D DEBUG_LOGGING=0 -D mqttDO_NOT_USE_CUSTOM_CONFIG -D MBEDTLS_CONFIG_FILE='<MbedtlsConfig.h>' -D__SL__ -D__OSI__ -D MBEDTLS_SHA256_C -D MBEDTLS_RSA_C -D MBEDTLS_PK_PARSE_C -D MBEDTLS_PK_C -D MBEDTLS_PEM_PARSE_C -D MBEDTLS_BASE64_C -D MBEDTLS_ASN1_PARSE_C -D MBEDTLS_PKCS1_V15 -D MBEDTLS_BIGNUM_C -D MBEDTLS_MD_C -D MBEDTLS_OID_C -D MBEDTLS_ENTROPY_C -D MBEDTLS_CTR_DRBG_C -D MBEDTLS_NO_PLATFORM_ENTROPY -D MBEDTLS_AES_C -D MBEDTLS_GENPRIME -O0 -g -I ./../Common/include -I ./../Common/include/Connectivity -I ./../Common/include/Connectivity/ServicePack -I ./../Common/include/Sensor -I ./../Common/source/Protected -I ./../Common/include/Utility -I ./../Common/legacy/include -I ./../Common/legacy/include/ServalPAL_WiFi -I ./../Common/legacy/include/BLE -I ./../Common/certs/XDKDummy -I ./../Common/certs/Custom -I ./../Common/config -I ./../Common/config/Drivers -I ./../Common/config/FOTA -I ./../Common/config/Utils -I ./../Common/config/ServalPal -I ./../Common/config/AmazonFreeRTOS/FreeRTOS -I ./../Common/config/AmazonFreeRTOS -I ./../Platform/BLE/include -I ./../Platform/BLE/include/services -I ./../Platform/Essentials/include -I ./../Platform/Drivers/include -I ./../Platform/Sensors/include -I ./../Platform/SensorUtils/include -I ./../Platform/ServalPAL/include -I ./../Platform/Utils/include -I ./../Platform/BSP/include -I ./../Platform/SensorToolbox/include -I ./../Platform/FOTA/include -I ./../Platform/FOTA/source/protected -I ./../Platform/Wlan/include -I ./../Common/config/Essentials -I ./../Common/config/LoRaDrivers -I ./../Platform/Essentials/include/bsp -I ./../Platform/Essentials/include/mcu/efm32 -I ./../Platform/Essentials/include/mcu -I ./../Platform/LoRaDrivers/include -I ./../Common/source/Adc -I ./../Common/source -I ./../Common/source/Private/ServalStack/src/TLS_MbedTLS -I ./../Common/include/Connectivity/LWM2M -I ./../Common/config/MbedTLS -isystem ./../Libraries/ServalStack/include -isystem ./../Libraries/ServalStack/3rd-party/ServalStack/api -isystem ./../Libraries/ServalStack/3rd-party/ServalStack/pal -isystem ./../Libraries/FreeRTOS/3rd-party/include -isystem ./../Libraries/FreeRTOS/3rd-party/include/private -isystem ./../Libraries/FreeRTOS/3rd-party/FreeRTOS/portable/GCC/ARM_CM3 -isystem ./../Libraries/EMlib/3rd-party/EMLib/emlib/inc -isystem ./../Libraries/EMlib/3rd-party/EMLib/Device/SiliconLabs/EFM32GG/Include -isystem ./../Libraries/EMlib/3rd-party/EMLib/CMSIS/Include -isystem ./../Libraries/FATfs/3rd-party/fatfs/src -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_CoreStack -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_CoreStack/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_CoreStack/Interfaces/ATT -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_CoreStack/Interfaces/Services -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_ALPWDataExchange/Interfaces -isystem ./../Libraries/WiFi/3rd-party/TI/simplelink/include -isystem ./../Libraries/WiFi/include -isystem ./../Libraries/WiFi/3rd-party/TI -isystem ./../Libraries/WiFi/3rd-party/TI/oslib -isystem ./../Libraries/WiFi/3rd-party/TI/netapps -isystem ./../Libraries/WiFi/3rd-party/TI/netapps/http/client -isystem ./../Libraries/WiFi/3rd-party/TI/simplelink/source -isystem ./../Libraries/BSX/BSX4/Source/algo/algo_bsx/Inc -isystem ./../Libraries/BSX/BSX4/Source/device/API/BMI160_API -isystem ./../Libraries/BSX/BSX4/Source/device/API/BMM050_API -isystem ./../Libraries/BSX/BSX4/Source/device/API/BMG160_API -isystem ./../Libraries/BSX/BSX4/Source/device/API/BMA2x2_API -isystem ./../Libraries/GridEye/3rd-party/GridEye/Source -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_AlertNotification/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_AppleNotificationCenter/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_BloodPressure/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_CyclingPower/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_CyclingSpeedAndCadence/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_FindMe/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_Glucose/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_HealthThermometer/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_HeartRate/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_HumanInterfaceDevice/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_iBeacon/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_LocationAndNavigation/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_PhoneAlertStatus/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_Proximity/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_RunningSpeedAndCadence/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_Time/Interfaces -isystem ./../Libraries/BLEStack/3rd-party/Alpwise/ALPW-BLESDKCM3/BLESW_WeightScale/Interfaces -isystem ./../Libraries/WiFi/3rd-party/TI/examples/common -isystem ./../Libraries/ServalStack/3rd-party/ServalStack/src/inc -isystem ./../Libraries/MbedTLS/3rd-party/mbedtls/include -isystem ./../Libraries/MbedTLS/3rd-party/mbedtls/include/mbedtls -isystem C:/XDK_on_Ethereum-master/mbedtls /include -isystem ./../Libraries/EMlib/3rd-party/EMLib/usb/inc -DBCDS_PACKAGE_ID=153 -c source/ExtensionPortSpi.c -o C:/XDK_on_Ethereum-master/debug/objects/source/ExtensionPortSpi.o
arm-none-eabi-gcc: error: /include: No such file or directory
application.mk:387: recipe for target 'C:/XDK_on_Ethereum-master/debug/objects/source/ExtensionPortSpi.o' failed
mingw32-make[1]: *** [C:/XDK_on_Ethereum-master/debug/objects/source/ExtensionPortSpi.o] Error 1
mingw32-make[1]: *** Waiting for unfinished jobs....

mingw32-make[2]: Leaving directory 'C:/XDK-Workbench/XDK/SDK/xdk110/Libraries/ServalStack'
mingw32-make[1]: Leaving directory 'C:/XDK-Workbench/XDK/SDK/xdk110/Common'
Makefile:64: recipe for target 'debug' failed
mingw32-make: *** [debug] Error 2

11:03:46 Build Finished (took 3m:2s.413ms)

I need help...

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.