├── ai-engine ├── init.py ├── main.py └── models │ ├── model.py │ └── data.py ├── iot-infrastructure ├── devices │ ├── init.py │ ├── controller.py │ └── device.py └── sensors │ ├── init.py │ └── sensor.py ├── docs ├── EcoPulse-Ecosystem.jpeg ├── guides │ ├── getting_started.md │ └── architecture.md └── tutorials │ └── building_an_app.md ├── .github └── ISSUE_TEMPLATE │ ├── custom.md │ ├── feature_request.md │ └── bug_report.md ├── .gitignore ├── sdk ├── tools │ ├── config_manager.py │ └── cli_tool.py └── libraries │ └── crypto_library.py ├── blockchain ├── node │ ├── config.go │ ├── ecopulse_node.go │ └── network.go ├── block.go ├── consensus.go ├── transaction.go ├── blockchain.go └── contracts │ ├── EcoPulseToken.sol │ ├── EcoPulseNFT.sol │ └── EcoPulseDAO.sol ├── README.md ├── defi-platform ├── borrowing │ └── borrowing_platform.py └── lending │ └── lending_platform.py └── LICENSE /ai-engine/init.py: -------------------------------------------------------------------------------- 1 | # Initialize the ai-engine package 2 | -------------------------------------------------------------------------------- /iot-infrastructure/devices/init.py: -------------------------------------------------------------------------------- 1 | # Initialize the devices package 2 | -------------------------------------------------------------------------------- /iot-infrastructure/sensors/init.py: -------------------------------------------------------------------------------- 1 | # Initialize the sensors package 2 | -------------------------------------------------------------------------------- /docs/EcoPulse-Ecosystem.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KOSASIH/ecopulse-ecosystem/HEAD/docs/EcoPulse-Ecosystem.jpeg -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore virtual environment files 2 | venv/ 3 | env/ 4 | 5 | # Ignore Python bytecode files 6 | *.pyc 7 | 8 | # Ignore IDE files 9 | *.iml 10 | .idea/ 11 | 12 | # Ignore node_modules folder 13 | node_modules/ 14 | 15 | # Ignore log files 16 | *.log 17 | 18 | # Ignore SDK build files 19 | sdk/build/ 20 | 21 | # Ignore data files 22 | data/*.csv 23 | data/*.json 24 | 25 | # Ignore other files 26 | *.tmp 27 | *.bak 28 | *.swp 29 | .DS_Store 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /sdk/tools/config_manager.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | class ConfigManager: 5 | def __init__(self, config_file="config.json"): 6 | self.config_file = config_file 7 | self.config = self.load_config() 8 | 9 | def load_config(self): 10 | if os.path.exists(self.config_file): 11 | with open(self.config_file, "r") as f: 12 | return json.load(f) 13 | else: 14 | return {} 15 | 16 | def save_config(self): 17 | with open(self.config_file, "w") as f: 18 | json.dump(self.config, f, indent=4) 19 | 20 | def get_config(self, key): 21 | return self.config.get(key) 22 | 23 | def set_config(self, key, value): 24 | self.config[key] = value 25 | self.save_config() 26 | 27 | # Example usage: 28 | if __name__ == "__main__": 29 | config_manager = ConfigManager() 30 | config_manager.set_config("api_key", "YOUR_API_KEY") 31 | print(config_manager.get_config("api_key")) 32 | -------------------------------------------------------------------------------- /blockchain/node/config.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "io/ioutil" 6 | "log" 7 | ) 8 | 9 | // Config represents the EcoPulse node configuration 10 | type Config struct { 11 | EthRPCURL string `json:"eth_rpc_url"` 12 | PrivateKey string `json:"private_key"` 13 | NetworkConfig `json:"network_config"` 14 | } 15 | 16 | // NetworkConfig represents the EcoPulse network configuration 17 | type NetworkConfig struct { 18 | NetworkID string `json:"network_id"` 19 | NodeID string `json:"node_id"` 20 | Peers []string `json:"peers"` 21 | ListenAddr string `json:"listen_addr"` 22 | } 23 | 24 | // LoadConfig loads the EcoPulse node configuration from a file 25 | func LoadConfig(filename string) (*Config, error) { 26 | var config Config 27 | 28 | data, err := ioutil.ReadFile(filename) 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | err = json.Unmarshal(data, &config) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | return &config, nil 39 | } 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ecopulse-ecosystem 2 | A Decentralized, AI-driven, and Sustainable Economic Framework for a Prosperous Future. 3 | 4 | EcoPulse Ecosystem 5 | ================ 6 | 7 | A Decentralized, AI-driven, and Sustainable Economic Framework for a Prosperous Future 8 | 9 | Welcome to the EcoPulse Ecosystem, a revolutionary platform that combines blockchain technology, artificial intelligence, and sustainable practices to create a prosperous future for all. 10 | 11 | Getting Started 12 | --------------- 13 | 14 | To get started with the EcoPulse Ecosystem, please refer to our [Getting Started Guide](docs/guides/getting_started.md). 15 | 16 | Documentation 17 | ------------ 18 | 19 | Our documentation is available in the [docs](docs) directory. 20 | 21 | * [Getting Started Guide](docs/guides/getting_started.md) 22 | * [EcoPulse Ecosystem Architecture](docs/guides/architecture.md) 23 | * [Building an App on EcoPulse Ecosystem](docs/tutorials/building_an_app.md) 24 | 25 | License 26 | ------- 27 | 28 | The EcoPulse Ecosystem is licensed under the Apache 2.0 License. See [LICENSE](LICENSE) for more information. 29 | 30 | Contributing 31 | ------------ 32 | 33 | We welcome contributions to the EcoPulse Ecosystem. Please refer to our [Contributing Guide](docs/contributing.md) for more information. 34 | 35 | -------------------------------------------------------------------------------- /ai-engine/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import argparse 3 | from ai_engine.models.data import DataProcessor 4 | from ai_engine.models.model import Model 5 | 6 | def main(): 7 | parser = argparse.ArgumentParser() 8 | parser.add_argument('--file_path', type=str, required=True) 9 | parser.add_argument('--learning_rate', type=float, default=0.001) 10 | parser.add_argument('--hidden_dim', type=int, default=128) 11 | parser.add_argument('--output_dim', type=int, default=10) 12 | args = parser.parse_args() 13 | 14 | file_path = args.file_path 15 | learning_rate = args.learning_rate 16 | hidden_dim = args.hidden_dim 17 | output_dim = args.output_dim 18 | 19 | data_processor = DataProcessor(file_path) 20 | data = data_processor.preprocess_data() 21 | X_train, X_test, y_train, y_test = data_processor.split_data() 22 | 23 | model = Model(X_train.shape[1], hidden_dim, output_dim, learning_rate) 24 | for epoch in range(10): 25 | model.train(X_train, y_train) 26 | y_pred = model.evaluate(X_test, y_test) 27 | accuracy, report, matrix = data_processor.evaluate_model(y_pred, y_test) 28 | print(f'Epoch {epoch+1}, Accuracy: {accuracy:.3f}') 29 | print(f'Classification Report:\n{report}') 30 | print(f'Confusion Matrix:\n{matrix}') 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /blockchain/block.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/sha256" 5 | "encoding/hex" 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | // Block represents an EcoPulse block 11 | type Block struct { 12 | Header *BlockHeader 13 | Transactions []*Transaction 14 | } 15 | 16 | // NewBlock creates a new EcoPulse block 17 | func NewBlock(header *BlockHeader, transactions []*Transaction) *Block { 18 | return &Block{ 19 | Header: header, 20 | Transactions: transactions, 21 | } 22 | } 23 | 24 | // Hash returns the block hash 25 | func (b *Block) Hash() string { 26 | hash := sha256.Sum256([]byte(fmt.Sprintf("%x%x%x", b.Header.Hash, b.Header.Timestamp, b.Header.Nonce))) 27 | return hex.EncodeToString(hash[:]) 28 | } 29 | 30 | // BlockHeader represents the header of an EcoPulse block 31 | type BlockHeader struct { 32 | Hash string 33 | Timestamp int64 34 | Nonce uint64 35 | PrevHash string 36 | } 37 | 38 | // NewBlockHeader creates a new EcoPulse block header 39 | func NewBlockHeader(prevHash string, nonce uint64) *BlockHeader { 40 | return &BlockHeader{ 41 | Timestamp: time.Now().UnixNano(), 42 | Nonce: nonce, 43 | PrevHash: prevHash, 44 | } 45 | } 46 | 47 | // Hash returns the block header hash 48 | func (h *BlockHeader) Hash() string { 49 | hash := sha256.Sum256([]byte(fmt.Sprintf("%x%x%x", h.Timestamp, h.Nonce, h.PrevHash))) 50 | return hex.EncodeToString(hash[:]) 51 | } 52 | -------------------------------------------------------------------------------- /docs/guides/getting_started.md: -------------------------------------------------------------------------------- 1 | Getting Started with EcoPulse Ecosystem 2 | ===================================== 3 | 4 | Welcome to the EcoPulse Ecosystem, a decentralized, AI-driven, and sustainable economic framework for a prosperous future. This guide will help you get started with the ecosystem and its various components. 5 | 6 | ### Prerequisites 7 | 8 | * Familiarity with blockchain technology and decentralized systems 9 | * Basic understanding of AI and machine learning concepts 10 | * Knowledge of programming languages such as Python or JavaScript 11 | 12 | ### Setting up the Ecosystem 13 | 14 | 1. Clone the EcoPulse Ecosystem repository: `git clone https://github.com/KOSASIH/ecopulse-ecosystem.git` 15 | 2. Install the required dependencies: `pip install -r requirements.txt` 16 | 3. Set up the ecosystem configuration: `python setup.py` 17 | 18 | ### Exploring the Ecosystem 19 | 20 | * Explore the `sdk` directory for the software development kit (SDK) and its various components 21 | * Check out the `docs` directory for guides, tutorials, and API documentation 22 | * Visit the [EcoPulse Ecosystem website](https://ecopulse.io) for more information and resources 23 | 24 | ### Next Steps 25 | 26 | * Read the [EcoPulse Ecosystem whitepaper](https://ecopulse.io/whitepaper.pdf) for a detailed overview of the ecosystem 27 | * Join the [EcoPulse Ecosystem community](https://discord.gg/ecopulse) to connect with other developers and stakeholders 28 | * Start building your own applications and integrations using the EcoPulse Ecosystem SDK 29 | -------------------------------------------------------------------------------- /iot-infrastructure/devices/controller.py: -------------------------------------------------------------------------------- 1 | import json 2 | import paho.mqtt.client as mqtt 3 | from iot_infrastructure.devices.device import Device 4 | 5 | class Controller: 6 | def __init__(self, mqtt_broker, mqtt_port): 7 | self.mqtt_broker = mqtt_broker 8 | self.mqtt_port = mqtt_port 9 | self.client = mqtt.Client() 10 | self.client.connect(self.mqtt_broker, self.mqtt_port) 11 | self.devices = {} 12 | 13 | def add_device(self, device): 14 | self.devices[device.device_id] = device 15 | 16 | def start_listening(self): 17 | # Subscribe to all device topics 18 | self.client.subscribe("devices/+") 19 | self.client.on_message = self.on_message 20 | self.client.loop_forever() 21 | 22 | def on_message(self, client, userdata, message): 23 | # Handle incoming message from a device 24 | device_id = message.topic.split("/")[1] 25 | data = json.loads(message.payload) 26 | print(f"Received data from device {device_id}: {data}") 27 | # Process the data here, e.g., store it in a database or trigger an action 28 | 29 | def send_command(self, device_id, command): 30 | # Send a command to a device 31 | self.client.publish(f"devices/{device_id}/commands", json.dumps({"command": command})) 32 | print(f"Sending command to device {device_id}: {command}") 33 | 34 | # Example usage: 35 | if __name__ == "__main__": 36 | controller = Controller("localhost", 1883) 37 | 38 | device1 = SmartHomeDevice("device1", "localhost", 1883) 39 | device2 = IndustrialDevice("device2", "localhost", 1883) 40 | 41 | controller.add_device(device1) 42 | controller.add_device(device2) 43 | 44 | controller.start_listening() 45 | -------------------------------------------------------------------------------- /blockchain/consensus.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | // Consensus represents the EcoPulse consensus algorithm 9 | type Consensus struct { 10 | Blockchain *Blockchain 11 | Mutex sync.RWMutex 12 | } 13 | 14 | // NewConsensus creates a new EcoPulse consensus algorithm 15 | func NewConsensus(blockchain *Blockchain) *Consensus { 16 | return &Consensus{ 17 | Blockchain: blockchain, 18 | } 19 | } 20 | 21 | // VerifyBlock verifies a block and adds it to the blockchain if valid 22 | func (c *Consensus) VerifyBlock(block *Block) error { 23 | c.Mutex.Lock() 24 | defer c.Mutex.Unlock() 25 | 26 | // Verify block hash 27 | hash := block.Hash() 28 | if hash != block.Header.Hash { 29 | return fmt.Errorf("invalid block hash") 30 | } 31 | 32 | // Verify block transactions 33 | for _, tx := range block.Transactions { 34 | if !tx.Verify() { 35 | return fmt.Errorf("invalid transaction signature") 36 | } 37 | } 38 | 39 | // Add block to blockchain 40 | c.Blockchain.AddBlock(block) 41 | 42 | return nil 43 | } 44 | 45 | // Mine mines a new block and adds it to the blockchain 46 | func (c *Consensus) Mine(transactions []*Transaction) (*Block, error) { 47 | c.Mutex.Lock() 48 | defer c.Mutex.Unlock() 49 | 50 | // Create new block header 51 | header := NewBlockHeader(c.Blockchain.CurrentBlock.Header.Hash, 0) 52 | 53 | // Create new block 54 | block := NewBlock(header, transactions) 55 | 56 | // Mine block 57 | for { 58 | header.Nonce++ 59 | block.Header = header 60 | hash := block.Hash() 61 | if hash < "0000000000000000000000000000000000000000000000000000000000000000" { 62 | break 63 | } 64 | } 65 | 66 | // Add block to blockchain 67 | c.Blockchain.AddBlock(block) 68 | 69 | return block, nil 70 | } 71 | -------------------------------------------------------------------------------- /blockchain/transaction.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/ecdsa" 5 | "crypto/rand" 6 | "crypto/sha256" 7 | "encoding/hex" 8 | "fmt" 9 | ) 10 | 11 | // Transaction represents an EcoPulse transaction 12 | type Transaction struct { 13 | ID string 14 | Sender *ecdsa.PublicKey 15 | Recipient *ecdsa.PublicKey 16 | Amount uint64 17 | Fee uint64 18 | Data []byte 19 | Signature []byte 20 | } 21 | 22 | // NewTransaction creates a new EcoPulse transaction 23 | func NewTransaction(sender, recipient *ecdsa.PublicKey, amount, fee uint64, data []byte) (*Transaction, error) { 24 | tx := &Transaction{ 25 | Sender: sender, 26 | Recipient: recipient, 27 | Amount: amount, 28 | Fee: fee, 29 | Data: data, 30 | } 31 | 32 | // Generate transaction ID 33 | hash := sha256.Sum256([]byte(fmt.Sprintf("%x%x%x%x", sender, recipient, amount, fee))) 34 | tx.ID = hex.EncodeToString(hash[:]) 35 | 36 | return tx, nil 37 | } 38 | 39 | // Hash returns the transaction hash 40 | func (t *Transaction) Hash() string { 41 | hash := sha256.Sum256([]byte(fmt.Sprintf("%x%x%x%x", t.Sender, t.Recipient, t.Amount, t.Fee))) 42 | return hex.EncodeToString(hash[:]) 43 | } 44 | 45 | // Sign signs the transaction with the sender's private key 46 | func (t *Transaction) Sign(privateKey *ecdsa.PrivateKey) error { 47 | hash := sha256.Sum256([]byte(t.ID)) 48 | signature, err := ecdsa.SignASN1(rand.Reader, privateKey, hash[:]) 49 | if err != nil { 50 | return err 51 | } 52 | 53 | t.Signature = signature 54 | 55 | return nil 56 | } 57 | 58 | // Verify verifies the transaction signature 59 | func (t *Transaction) Verify() bool { 60 | hash := sha256.Sum256([]byte(t.ID)) 61 | return ecdsa.VerifyASN1(t.Sender, hash[:], t.Signature) 62 | } 63 | -------------------------------------------------------------------------------- /defi-platform/borrowing/borrowing_platform.py: -------------------------------------------------------------------------------- 1 | import json 2 | import web3 3 | from web3 import Web3, HTTPProvider 4 | 5 | class BorrowingPlatform: 6 | def __init__(self, ethereum_node, borrowing_contract_address): 7 | self.ethereum_node = ethereum_node 8 | self.borrowing_contract_address = borrowing_contract_address 9 | self.web3 = Web3(HTTPProvider(self.ethereum_node)) 10 | self.contract = self.web3.eth.contract(address=self.borrowing_contract_address, abi=self.get_abi()) 11 | 12 | def get_abi(self): 13 | # Load the borrowing contract ABI from a file or database 14 | with open("borrowing_contract_abi.json", "r") as f: 15 | return json.load(f) 16 | 17 | def request_loan(self, user_address, amount, interest_rate): 18 | # Request a loan from the borrowing platform 19 | tx_hash = self.contract.functions.requestLoan(user_address, amount, interest_rate).transact({"from": user_address}) 20 | self.web3.eth.waitForTransactionReceipt(tx_hash) 21 | print(f"Requested loan of {amount} at {interest_rate}% interest rate for user {user_address}") 22 | 23 | def repay_loan(self, user_address, amount): 24 | # Repay a loan to the borrowing platform 25 | tx_hash = self.contract.functions.repayLoan(user_address, amount).transact({"from": user_address}) 26 | self.web3.eth.waitForTransactionReceipt(tx_hash) 27 | print(f"Repaid loan of {amount} for user {user_address}") 28 | 29 | def get_loan_status(self, user_address): 30 | # Get the loan status for a user 31 | loan_status = self.contract.functions.getLoanStatus(user_address).call() 32 | print(f"Loan status for user {user_address}: {loan_status}") 33 | 34 | # Example usage: 35 | if __name__ == "__main__": 36 | borrowing_platform = BorrowingPlatform("https://mainnet.infura.io/v3/YOUR_PROJECT_ID", "0x...BorrowingContractAddress") 37 | user_address = "0x...UserAddress" 38 | borrowing_platform.request_loan(user_address, 0.5, 10.0) 39 | borrowing_platform.repay_loan(user_address, 0.2) 40 | borrowing_platform.get_loan_status(user_address) 41 | -------------------------------------------------------------------------------- /defi-platform/lending/lending_platform.py: -------------------------------------------------------------------------------- 1 | import json 2 | import web3 3 | from web3 import Web3, HTTPProvider 4 | 5 | class LendingPlatform: 6 | def __init__(self, ethereum_node, lending_contract_address): 7 | self.ethereum_node = ethereum_node 8 | self.lending_contract_address = lending_contract_address 9 | self.web3 = Web3(HTTPProvider(self.ethereum_node)) 10 | self.contract = self.web3.eth.contract(address=self.lending_contract_address, abi=self.get_abi()) 11 | 12 | def get_abi(self): 13 | # Load the lending contract ABI from a file or database 14 | with open("lending_contract_abi.json", "r") as f: 15 | return json.load(f) 16 | 17 | def deposit(self, user_address, amount): 18 | # Deposit funds into the lending platform 19 | tx_hash = self.contract.functions.deposit(user_address, amount).transact({"from": user_address}) 20 | self.web3.eth.waitForTransactionReceipt(tx_hash) 21 | print(f"Deposited {amount} to lending platform for user {user_address}") 22 | 23 | def lend(self, user_address, amount, interest_rate): 24 | # Lend funds to another user 25 | tx_hash = self.contract.functions.lend(user_address, amount, interest_rate).transact({"from": user_address}) 26 | self.web3.eth.waitForTransactionReceipt(tx_hash) 27 | print(f"Lent {amount} to user {user_address} at {interest_rate}% interest rate") 28 | 29 | def withdraw(self, user_address, amount): 30 | # Withdraw funds from the lending platform 31 | tx_hash = self.contract.functions.withdraw(user_address, amount).transact({"from": user_address}) 32 | self.web3.eth.waitForTransactionReceipt(tx_hash) 33 | print(f"Withdrew {amount} from lending platform for user {user_address}") 34 | 35 | # Example usage: 36 | if __name__ == "__main__": 37 | lending_platform = LendingPlatform("https://mainnet.infura.io/v3/YOUR_PROJECT_ID", "0x...LendingContractAddress") 38 | user_address = "0x...UserAddress" 39 | lending_platform.deposit(user_address, 1.0) 40 | lending_platform.lend(user_address, 0.5, 10.0) 41 | lending_platform.withdraw(user_address, 0.2) 42 | -------------------------------------------------------------------------------- /docs/guides/architecture.md: -------------------------------------------------------------------------------- 1 | EcoPulse Ecosystem Architecture 2 | ============================= 3 | 4 | The EcoPulse Ecosystem is a decentralized, AI-driven, and sustainable economic framework that consists of several components. This guide provides an overview of the ecosystem's architecture and its various components. 5 | 6 | ### Components 7 | 8 | * **SDK**: The software development kit (SDK) provides a set of tools and libraries for building applications and integrations on top of the EcoPulse Ecosystem. 9 | * **AI Engine**: The AI engine is a decentralized AI platform that provides machine learning and predictive analytics capabilities to the ecosystem. 10 | * **Blockchain**: The blockchain component provides a decentralized and secure ledger for storing and managing data and transactions within the ecosystem. 11 | * **Data Hub**: The data hub is a centralized repository for storing and managing data from various sources within the ecosystem. 12 | 13 | ### Architecture Diagram 14 | 15 | +---------------+ 16 | | SDK | 17 | +---------------+ 18 | | 19 | | 20 | v 21 | +---------------+ 22 | | AI Engine | 23 | +---------------+ 24 | | 25 | | 26 | v 27 | +---------------+ 28 | | Blockchain | 29 | +---------------+ 30 | | 31 | | 32 | v 33 | +---------------+ 34 | | Data Hub | 35 | +---------------+ 36 | 37 | 38 | 39 | ### Interactions 40 | 41 | * The SDK interacts with the AI engine to provide machine learning and predictive analytics capabilities to applications and integrations. 42 | * The AI engine interacts with the blockchain to store and manage data and transactions. 43 | * The blockchain interacts with the data hub to store and manage data from various sources. 44 | * The data hub interacts with the SDK to provide data and insights to applications and integrations. 45 | 46 | ### Benefits 47 | 48 | * Decentralized and secure architecture 49 | * AI-driven insights and predictions 50 | * Sustainable and environmentally friendly 51 | * Scalable and flexible architecture 52 | -------------------------------------------------------------------------------- /iot-infrastructure/sensors/sensor.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | import threading 4 | import json 5 | import paho.mqtt.client as mqtt 6 | 7 | class Sensor: 8 | def __init__(self, sensor_id, sensor_type, mqtt_broker, mqtt_port): 9 | self.sensor_id = sensor_id 10 | self.sensor_type = sensor_type 11 | self.mqtt_broker = mqtt_broker 12 | self.mqtt_port = mqtt_port 13 | self.client = mqtt.Client() 14 | self.client.connect(self.mqtt_broker, self.mqtt_port) 15 | self.data = {} 16 | 17 | def read_data(self): 18 | # Simulate reading data from the sensor 19 | data = random.uniform(0, 100) 20 | self.data[self.sensor_type] = data 21 | return data 22 | 23 | def send_data(self): 24 | # Send data to the MQTT broker 25 | self.client.publish(f"sensors/{self.sensor_id}/{self.sensor_type}", json.dumps(self.data)) 26 | print(f"Sending data from sensor {self.sensor_id} of type {self.sensor_type}: {self.data}") 27 | 28 | def start(self): 29 | # Start a thread to read and send data every 10 seconds 30 | def read_and_send_data(): 31 | while True: 32 | self.read_data() 33 | self.send_data() 34 | time.sleep(10) 35 | threading.Thread(target=read_and_send_data).start() 36 | 37 | class TemperatureSensor(Sensor): 38 | def __init__(self, sensor_id, mqtt_broker, mqtt_port): 39 | super().__init__(sensor_id, "temperature", mqtt_broker, mqtt_port) 40 | 41 | class HumiditySensor(Sensor): 42 | def __init__(self, sensor_id, mqtt_broker, mqtt_port): 43 | super().__init__(sensor_id, "humidity", mqtt_broker, mqtt_port) 44 | 45 | class PressureSensor(Sensor): 46 | def __init__(self, sensor_id, mqtt_broker, mqtt_port): 47 | super().__init__(sensor_id, "pressure", mqtt_broker, mqtt_port) 48 | 49 | # Example usage: 50 | if __name__ == "__main__": 51 | sensor1 = TemperatureSensor("sensor1", "localhost", 1883) 52 | sensor2 = HumiditySensor("sensor2", "localhost", 1883) 53 | sensor3 = PressureSensor("sensor3", "localhost", 1883) 54 | 55 | sensor1.start() 56 | sensor2.start() 57 | sensor3.start() 58 | 59 | while True: 60 | time.sleep(1) 61 | -------------------------------------------------------------------------------- /blockchain/blockchain.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/sha256" 5 | "encoding/hex" 6 | "fmt" 7 | "log" 8 | "sync" 9 | 10 | "github.com/ethereum/go-ethereum/core/types" 11 | ) 12 | 13 | // Blockchain represents the EcoPulse blockchain 14 | type Blockchain struct { 15 | Blocks []*Block 16 | Chain []*types.Block 17 | CurrentBlock *Block 18 | Transactions []*Transaction 19 | Mutex sync.RWMutex 20 | } 21 | 22 | // NewBlockchain creates a new EcoPulse blockchain 23 | func NewBlockchain() *Blockchain { 24 | return &Blockchain{ 25 | Blocks: make([]*Block, 0), 26 | Chain: make([]*types.Block, 0), 27 | } 28 | } 29 | 30 | // AddBlock adds a new block to the blockchain 31 | func (b *Blockchain) AddBlock(block *Block) error { 32 | b.Mutex.Lock() 33 | defer b.Mutex.Unlock() 34 | 35 | // Verify block hash 36 | hash := block.Hash() 37 | if hash != block.Header.Hash { 38 | return fmt.Errorf("invalid block hash") 39 | } 40 | 41 | // Add block to chain 42 | b.Chain = append(b.Chain, block) 43 | 44 | // Update current block 45 | b.CurrentBlock = block 46 | 47 | return nil 48 | } 49 | 50 | // AddTransaction adds a new transaction to the blockchain 51 | func (b *Blockchain) AddTransaction(tx *Transaction) error { 52 | b.Mutex.Lock() 53 | defer b.Mutex.Unlock() 54 | 55 | // Verify transaction hash 56 | hash := tx.Hash() 57 | if hash != tx.ID { 58 | return fmt.Errorf("invalid transaction hash") 59 | } 60 | 61 | // Add transaction to transactions pool 62 | b.Transactions = append(b.Transactions, tx) 63 | 64 | return nil 65 | } 66 | 67 | // GetBlock returns a block by its hash 68 | func (b *Blockchain) GetBlock(hash string) (*Block, error) { 69 | b.Mutex.RLock() 70 | defer b.Mutex.RUnlock() 71 | 72 | for _, block := range b.Chain { 73 | if block.Hash() == hash { 74 | return block, nil 75 | } 76 | } 77 | 78 | return nil, fmt.Errorf("block not found") 79 | } 80 | 81 | // GetTransaction returns a transaction by its hash 82 | func (b *Blockchain) GetTransaction(hash string) (*Transaction, error) { 83 | b.Mutex.RLock() 84 | defer b.Mutex.RUnlock() 85 | 86 | for _, tx := range b.Transactions { 87 | if tx.Hash() == hash { 88 | return tx, nil 89 | } 90 | } 91 | 92 | return nil, fmt.Errorf("transaction not found") 93 | } 94 | -------------------------------------------------------------------------------- /iot-infrastructure/devices/device.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | import threading 4 | import json 5 | import paho.mqtt.client as mqtt 6 | 7 | class Device: 8 | def __init__(self, device_id, device_type, mqtt_broker, mqtt_port): 9 | self.device_id = device_id 10 | self.device_type = device_type 11 | self.mqtt_broker = mqtt_broker 12 | self.mqtt_port = mqtt_port 13 | self.client = mqtt.Client() 14 | self.client.connect(self.mqtt_broker, self.mqtt_port) 15 | self.sensors = {} 16 | self.data = {} 17 | 18 | def add_sensor(self, sensor): 19 | self.sensors[sensor.sensor_type] = sensor 20 | 21 | def read_data(self): 22 | # Read data from all sensors 23 | for sensor_type, sensor in self.sensors.items(): 24 | self.data[sensor_type] = sensor.read_data() 25 | return self.data 26 | 27 | def send_data(self): 28 | # Send data to the MQTT broker 29 | self.client.publish(f"devices/{self.device_id}", json.dumps(self.data)) 30 | print(f"Sending data from device {self.device_id} of type {self.device_type}: {self.data}") 31 | 32 | def start(self): 33 | # Start a thread to read and send data every 10 seconds 34 | def read_and_send_data(): 35 | while True: 36 | self.read_data() 37 | self.send_data() 38 | time.sleep(10) 39 | threading.Thread(target=read_and_send_data).start() 40 | 41 | class SmartHomeDevice(Device): 42 | def __init__(self, device_id, mqtt_broker, mqtt_port): 43 | super().__init__(device_id, "smart_home", mqtt_broker, mqtt_port) 44 | 45 | class IndustrialDevice(Device): 46 | def __init__(self, device_id, mqtt_broker, mqtt_port): 47 | super().__init__(device_id, "industrial", mqtt_broker, mqtt_port) 48 | 49 | # Example usage: 50 | if __name__ == "__main__": 51 | device1 = SmartHomeDevice("device1", "localhost", 1883) 52 | device2 = IndustrialDevice("device2", "localhost", 1883) 53 | 54 | sensor1 = TemperatureSensor("sensor1", "localhost", 1883) 55 | sensor2 = HumiditySensor("sensor2", "localhost", 1883) 56 | sensor3 = PressureSensor("sensor3", "localhost", 1883) 57 | 58 | device1.add_sensor(sensor1) 59 | device1.add_sensor(sensor2) 60 | device2.add_sensor(sensor3) 61 | 62 | device1.start() 63 | device2.start() 64 | 65 | while True: 66 | time.sleep(1) 67 | -------------------------------------------------------------------------------- /docs/tutorials/building_an_app.md: -------------------------------------------------------------------------------- 1 | Building an App on EcoPulse Ecosystem 2 | ===================================== 3 | 4 | This tutorial will guide you through the process of building a simple application on top of the EcoPulse Ecosystem using the SDK. 5 | 6 | ### Prerequisites 7 | 8 | * Familiarity with the EcoPulse Ecosystem architecture and components 9 | * Knowledge of programming languages such as Python or JavaScript 10 | * Basic understanding of blockchain technology and decentralized systems 11 | 12 | ### Step 1: Set up the SDK 13 | 14 | * Clone the EcoPulse Ecosystem repository: `git clone https://github.com/KOSASIH/ecopulse-ecosystem.git` 15 | * Install the required dependencies: `pip install -r requirements.txt` 16 | * Set up the ecosystem configuration: `python setup.py` 17 | 18 | ### Step 2: Create a New App 19 | 20 | * Create a new directory for your app: `mkdir my_app` 21 | * Create a new file `app.py` and add the following code: 22 | ```python 23 | 1. from sdk import EcoPulseSDK 24 | 2. 25 | 3. sdk = EcoPulseSDK() 26 | 4. 27 | 5. # Initialize the app 28 | 6. sdk.init_app("my_app") 29 | 7. 30 | 8. # Define a function to interact with the AI engine 31 | 9. def predict_data(data): 32 | 10. ai_engine = sdk.get_ai_engine() 33 | 11. prediction = ai_engine.predict(data) 34 | 12. return prediction 35 | 13. 36 | 14. # Define a function to interact with the blockchain 37 | 15. def store_data(data): 38 | 16. blockchain = sdk.get_blockchain() 39 | 17. blockchain.store_data(data) 40 | 18. return True 41 | 19. 42 | 20. # Define a function to interact with the data hub 43 | 21. def retrieve_data(): 44 | 22. data = data_hub.retrieve_data() 45 | 23. return data 46 | 24. 47 | 25. # Run the app 48 | 26. if __name__ == "__main__": 49 | 27. predict_data("some_data") 50 | 28. store_data("some_data") 51 | 29. retrieve_data() 52 | ``` 53 | 54 | ### Step 3: Run the App 55 | 56 | Run the app using Python: python app.py 57 | 58 | ### Step 4: Integrate with the EcoPulse Ecosystem 59 | 60 | Integrate your app with the EcoPulse Ecosystem by using the SDK to interact with the AI engine, blockchain, and data hub. 61 | Use the EcoPulseSDK class to initialize the app and access the various components of the ecosystem. 62 | 63 | # Conclusion 64 | Congratulations! You have successfully built a simple application on top of the EcoPulse Ecosystem using the SDK. This is just the beginning of your journey in building innovative applications and integrations on the EcoPulse Ecosystem. 65 | -------------------------------------------------------------------------------- /blockchain/contracts/EcoPulseToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol"; 4 | import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol"; 5 | 6 | contract EcoPulseToken { 7 | // Token details 8 | string public name = "EcoPulse Token"; 9 | string public symbol = "EP"; 10 | uint8 public decimals = 18; 11 | uint256 public totalSupply = 10_000_000_000 * (10 ** decimals); 12 | 13 | // Mapping of balances 14 | mapping (address => uint256) public balances; 15 | 16 | // Mapping of allowances 17 | mapping (address => mapping (address => uint256)) public allowances; 18 | 19 | // Event emitted when tokens are transferred 20 | event Transfer(address indexed from, address indexed to, uint256 value); 21 | 22 | // Event emitted when approval is given 23 | event Approval(address indexed owner, address indexed spender, uint256 value); 24 | 25 | // Constructor 26 | constructor() public { 27 | // Initialize token balances 28 | balances[msg.sender] = totalSupply; 29 | } 30 | 31 | // Transfer tokens 32 | function transfer(address to, uint256 value) public returns (bool) { 33 | require(balances[msg.sender] >= value, "Insufficient balance"); 34 | balances[msg.sender] -= value; 35 | balances[to] += value; 36 | emit Transfer(msg.sender, to, value); 37 | return true; 38 | } 39 | 40 | // Approve tokens for spending 41 | function approve(address spender, uint256 value) public returns (bool) { 42 | allowances[msg.sender][spender] = value; 43 | emit Approval(msg.sender, spender, value); 44 | return true; 45 | } 46 | 47 | // Transfer tokens from one address to another 48 | function transferFrom(address from, address to, uint256 value) public returns (bool) { 49 | require(allowances[from][msg.sender] >= value, "Insufficient allowance"); 50 | require(balances[from] >= value, "Insufficient balance"); 51 | balances[from] -= value; 52 | balances[to] += value; 53 | allowances[from][msg.sender] -= value; 54 | emit Transfer(from, to, value); 55 | return true; 56 | } 57 | 58 | // Get token balance 59 | function balanceOf(address owner) public view returns (uint256) { 60 | return balances[owner]; 61 | } 62 | 63 | // Get token allowance 64 | function allowance(address owner, address spender) public view returns (uint256) { 65 | return allowances[owner][spender]; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /blockchain/contracts/EcoPulseNFT.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC721/SafeERC721.sol"; 4 | import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol"; 5 | 6 | contract EcoPulseNFT { 7 | // NFT details 8 | string public name = "EcoPulse NFT"; 9 | string public symbol = "EPNFT"; 10 | 11 | // Mapping of NFTs 12 | mapping (uint256 => address) public nftOwners; 13 | 14 | // Mapping of NFT metadata 15 | mapping (uint256 => string) public nftMetadata; 16 | 17 | // Event emitted when NFT is minted 18 | event Mint(address indexed owner, uint256 indexed tokenId, string metadata); 19 | 20 | // Event emitted when NFT is transferred 21 | event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); 22 | 23 | // Event emitted when NFT is burned 24 | event Burn(address indexed owner, uint256 indexed tokenId); 25 | 26 | // Constructor 27 | constructor() public { 28 | // Initialize NFT counter 29 | uint256 public nftCounter = 0; 30 | } 31 | 32 | // Mint a new NFT 33 | function mint(address to, string memory metadata) public returns (uint256) { 34 | require(to != address(0), "Invalid recipient"); 35 | uint256 tokenId = nftCounter++; 36 | nftOwners[tokenId] = to; 37 | nftMetadata[tokenId] = metadata; 38 | emit Mint(to, tokenId, metadata); 39 | return tokenId; 40 | } 41 | 42 | // Transfer NFT 43 | function transfer(address to, uint256 tokenId) public returns (bool) { 44 | require(nftOwners[tokenId] == msg.sender, "Only the owner can transfer"); 45 | require(to != address(0), "Invalid recipient"); 46 | nftOwners[tokenId] = to; 47 | emit Transfer(msg.sender, to, tokenId); 48 | return true; 49 | } 50 | 51 | // Burn NFT 52 | function burn(uint256 tokenId) public returns (bool) { 53 | require(nftOwners[tokenId] == msg.sender, "Only the owner can burn"); 54 | delete nftOwners[tokenId]; 55 | delete nftMetadata[tokenId]; 56 | emit Burn(msg.sender, tokenId); 57 | return true; 58 | } 59 | 60 | // Get NFT owner 61 | function ownerOf(uint256 tokenId) public view returns (address) { 62 | return nftOwners[tokenId]; 63 | } 64 | 65 | // Get NFT metadata 66 | function getMetadata(uint256 tokenId) public view returns (string memory) { 67 | return nftMetadata[tokenId]; 68 | } 69 | 70 | // Get NFT count 71 | function getNFTCount() public view returns (uint256) { 72 | return nftCounter; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /blockchain/node/ecopulse_node.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/ecdsa" 5 | "crypto/rand" 6 | "crypto/sha256" 7 | "encoding/hex" 8 | "encoding/json" 9 | "fmt" 10 | "log" 11 | "net/http" 12 | "sync" 13 | 14 | "github.com/dgrijalva/jwt-go" 15 | "github.com/ethereum/go-ethereum/accounts" 16 | "github.com/ethereum/go-ethereum/common" 17 | "github.com/ethereum/go-ethereum/core/types" 18 | "github.com/ethereum/go-ethereum/ethclient" 19 | ) 20 | 21 | // Node represents an EcoPulse node 22 | type Node struct { 23 | Config *Config 24 | EthClient *ethclient.Client 25 | PrivateKey *ecdsa.PrivateKey 26 | PublicKey *ecdsa.PublicKey 27 | Network *Network 28 | } 29 | 30 | // NewNode creates a new EcoPulse node 31 | func NewNode(config *Config) (*Node, error) { 32 | node := &Node{ 33 | Config: config, 34 | } 35 | 36 | // Initialize Ethereum client 37 | client, err := ethclient.Dial(config.EthRPCURL) 38 | if err != nil { 39 | return nil, err 40 | } 41 | node.EthClient = client 42 | 43 | // Initialize private and public keys 44 | privateKey, err := hex.DecodeString(config.PrivateKey) 45 | if err != nil { 46 | return nil, err 47 | } 48 | node.PrivateKey, err = ecdsa.GenerateKey(ecdsa.S256(), privateKey) 49 | if err != nil { 50 | return nil, err 51 | } 52 | node.PublicKey = &node.PrivateKey.PublicKey 53 | 54 | // Initialize network 55 | node.Network, err = NewNetwork(config.NetworkConfig) 56 | if err != nil { 57 | return nil, err 58 | } 59 | 60 | return node, nil 61 | } 62 | 63 | // Start starts the EcoPulse node 64 | func (n *Node) Start() error { 65 | // Start network 66 | err := n.Network.Start() 67 | if err != nil { 68 | return err 69 | } 70 | 71 | // Start HTTP server 72 | http.HandleFunc("/api/v1/contracts", n.handleContracts) 73 | http.HandleFunc("/api/v1/nfts", n.handleNFTs) 74 | http.HandleFunc("/api/v1/proposals", n.handleProposals) 75 | http.HandleFunc("/api/v1/votes", n.handleVotes) 76 | log.Fatal(http.ListenAndServe(":8080", nil)) 77 | 78 | return nil 79 | } 80 | 81 | func (n *Node) handleContracts(w http.ResponseWriter, r *http.Request) { 82 | // Handle contracts API 83 | } 84 | 85 | func (n *Node) handleNFTs(w http.ResponseWriter, r *http.Request) { 86 | // Handle NFTs API 87 | } 88 | 89 | func (n *Node) handleProposals(w http.ResponseWriter, r *http.Request) { 90 | // Handle proposals API 91 | } 92 | 93 | func (n *Node) handleVotes(w http.ResponseWriter, r *http.Request) { 94 | // Handle votes API 95 | } 96 | 97 | func main() { 98 | config, err := LoadConfig("config.json") 99 | if err != nil { 100 | log.Fatal(err) 101 | } 102 | 103 | node, err := NewNode(config) 104 | if err != nil { 105 | log.Fatal(err) 106 | } 107 | 108 | err = node.Start() 109 | if err != nil { 110 | log.Fatal(err) 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /sdk/libraries/crypto_library.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import hmac 3 | from cryptography.hazmat.primitives import serialization 4 | from cryptography.hazmat.primitives.asymmetric import rsa 5 | from cryptography.hazmat.backends import default_backend 6 | 7 | class CryptoLibrary: 8 | def __init__(self): 9 | self.backend = default_backend() 10 | 11 | def generate_key_pair(self): 12 | # Generate a new RSA key pair 13 | key = rsa.generate_private_key( 14 | public_exponent=65537, 15 | key_size=2048, 16 | backend=self.backend 17 | ) 18 | return key 19 | 20 | def sign_data(self, private_key, data): 21 | # Sign data using a private key 22 | signer = hmac.HMAC(private_key, hashlib.sha256, backend=self.backend) 23 | signer.update(data) 24 | return signer.finalize() 25 | 26 | def verify_signature(self, public_key, data, signature): 27 | # Verify a signature using a public key 28 | verifier = hmac.HMAC(public_key, hashlib.sha256, backend=self.backend) 29 | verifier.update(data) 30 | try: 31 | verifier.verify(signature) 32 | return True 33 | except ValueError: 34 | return False 35 | 36 | def encrypt_data(self, public_key, data): 37 | # Encrypt data using a public key 38 | cipher_text = public_key.encrypt( 39 | data, 40 | padding.OAEP( 41 | mgf=padding.MGF1(algorithm=hashlib.sha256()), 42 | algorithm=hashlib.sha256(), 43 | label=None 44 | ) 45 | ) 46 | return cipher_text 47 | 48 | def decrypt_data(self, private_key, cipher_text): 49 | # Decrypt data using a private key 50 | plain_text = private_key.decrypt( 51 | cipher_text, 52 | padding.OAEP( 53 | mgf=padding.MGF1(algorithm=hashlib.sha256()), 54 | algorithm=hashlib.sha256(), 55 | label=None 56 | ) 57 | ) 58 | return plain_text 59 | 60 | # Example usage: 61 | if __name__ == "__main__": 62 | crypto_lib = CryptoLibrary() 63 | key_pair = crypto_lib.generate_key_pair() 64 | private_key = key_pair.private_bytes( 65 | encoding=serialization.Encoding.PEM, 66 | format=serialization.PrivateFormat.PKCS8, 67 | encryption_algorithm=serialization.NoEncryption() 68 | ) 69 | public_key = key_pair.public_key().public_bytes( 70 | encoding=serialization.Encoding.OpenSSH, 71 | format=serialization.PublicFormat.OpenSSH 72 | ) 73 | 74 | data = b"Hello, World!" 75 | signature = crypto_lib.sign_data(private_key, data) 76 | print(f"Signature: {signature.hex()}") 77 | 78 | verified = crypto_lib.verify_signature(public_key, data, signature) 79 | print(f"Verified: {verified}") 80 | 81 | cipher_text = crypto_lib.encrypt_data(public_key, data) 82 | print(f"Cipher Text: {cipher_text.hex()}") 83 | 84 | plain_text = crypto_lib.decrypt_data(private_key, cipher_text) 85 | print(f"Plain Text: {plain_text.decode('utf-8')}") 86 | -------------------------------------------------------------------------------- /blockchain/node/network.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/rand" 5 | "encoding/hex" 6 | "fmt" 7 | "log" 8 | "net" 9 | "sync" 10 | 11 | "github.com/libp2p/go-libp2p-core/network" 12 | "github.com/libp2p/go-libp2p-core/peer" 13 | ) 14 | 15 | // Network represents the EcoPulse network 16 | type Network struct { 17 | Config *NetworkConfig 18 | Peers map[string]*peer.Peer 19 | ListenAddr string 20 | } 21 | 22 | // NewNetwork creates a new EcoPulse network 23 | func NewNetwork(config *NetworkConfig) (*Network, error) { 24 | network := &Network{ 25 | Config: config, 26 | Peers: make(map[string]*peer.Peer), 27 | } 28 | 29 | // Initialize libp2p network 30 | host, err := network.NewHost( 31 | config.NetworkID, 32 | config.NodeID, 33 | config.Peers, 34 | config.ListenAddr, 35 | ) 36 | if err != nil { 37 | return nil, err 38 | } 39 | 40 | network.Host = host 41 | 42 | // Start listening for incoming connections 43 | lis, err := net.Listen("tcp", config.ListenAddr) 44 | if err != nil { 45 | return nil, err 46 | } 47 | defer lis.Close() 48 | 49 | log.Println("Listening on", config.ListenAddr) 50 | 51 | // Start libp2p network 52 | err = network.Host.SetListenCloseFunc(func(ln net.Listener) { 53 | ln.Close() 54 | }) 55 | if err != nil { 56 | return nil, err 57 | } 58 | 59 | err = network.Host.SetStreamHandler(protocol.ID("/ecopulse/1.0.0"), network.handleStream) 60 | if err != nil { 61 | return nil, err 62 | } 63 | 64 | return network, nil 65 | } 66 | 67 | // handleStream handles incoming streams 68 | func (n *Network) handleStream(s network.Stream) { 69 | log.Println("Incoming stream from", s.Conn().RemotePeer()) 70 | 71 | // Handle stream data 72 | buf := make([]byte, 1024) 73 | _, err := s.Read(buf) 74 | if err != nil { 75 | log.Println(err) 76 | return 77 | } 78 | 79 | log.Println("Received data:", string(buf)) 80 | 81 | // Send response back 82 | _, err = s.Write([]byte("Hello from EcoPulse!")) 83 | if err != nil { 84 | log.Println(err) 85 | return 86 | } 87 | } 88 | 89 | // Connect connects to a peer 90 | func (n *Network) Connect(peerID string) error { 91 | pi, err := peer.Decode(peerID) 92 | if err != nil { 93 | return err 94 | } 95 | 96 | err = n.Host.Connect(context.Background(), pi) 97 | if err != nil { 98 | return err 99 | } 100 | 101 | log.Println("Connected to", peerID) 102 | 103 | return nil 104 | } 105 | 106 | // Disconnect disconnects from a peer 107 | func (n *Network) Disconnect(peerID string) error { 108 | pi, err := peer.Decode(peerID) 109 | if err != nil { 110 | return err 111 | } 112 | 113 | err = n.Host.CloseConnection(pi) 114 | if err != nil { 115 | return err 116 | } 117 | 118 | log.Println("Disconnected from", peerID) 119 | 120 | return nil 121 | } 122 | 123 | // Send sends data to a peer 124 | func (n *Network) Send(peerID string, data []byte) error { 125 | pi, err := peer.Decode(peerID) 126 | if err != nil { 127 | return err 128 | } 129 | 130 | s, err := n.Host.NewStream(context.Background(), pi, protocol.ID("/ecopulse/1.0.0")) 131 | if err != nil { 132 | return err 133 | } 134 | 135 | _, err = s.Write(data) 136 | if err != nil { 137 | return err 138 | } 139 | 140 | return nil 141 | } 142 | 143 | // Start starts the EcoPulse network 144 | func (n *Network) Start() error { 145 | log.Println("Starting EcoPulse network") 146 | 147 | return nil 148 | } 149 | -------------------------------------------------------------------------------- /ai-engine/models/model.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn as nn 3 | import torch.optim as optim 4 | from torch.utils.data import Dataset, DataLoader 5 | from sklearn.metrics import accuracy_score, classification_report, confusion_matrix 6 | import numpy as np 7 | 8 | class NeuralNetwork(nn.Module): 9 | def __init__(self, input_dim, hidden_dim, output_dim): 10 | super(NeuralNetwork, self).__init__() 11 | self.fc1 = nn.Linear(input_dim, hidden_dim) 12 | self.fc2 = nn.Linear(hidden_dim, hidden_dim) 13 | self.fc3 = nn.Linear(hidden_dim, output_dim) 14 | 15 | def forward(self, x): 16 | x = torch.relu(self.fc1(x)) 17 | x = torch.relu(self.fc2(x)) 18 | x = self.fc3(x) 19 | return x 20 | 21 | class ConvolutionalNeuralNetwork(nn.Module): 22 | def __init__(self, input_dim, hidden_dim, output_dim): 23 | super(ConvolutionalNeuralNetwork, self).__init__() 24 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 25 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 26 | self.fc1 = nn.Linear(320, hidden_dim) 27 | self.fc2 = nn.Linear(hidden_dim, output_dim) 28 | 29 | def forward(self, x): 30 | x = torch.relu(torch.max_pool2d(self.conv1(x), 2)) 31 | x = torch.relu(torch.max_pool2d(self.conv2(x), 2)) 32 | x = x.view(-1, 320) 33 | x = torch.relu(self.fc1(x)) 34 | x = self.fc2(x) 35 | return x 36 | 37 | class RecurrentNeuralNetwork(nn.Module): 38 | def __init__(self, input_dim, hidden_dim, output_dim): 39 | super(RecurrentNeuralNetwork, self).__init__() 40 | self.rnn = nn.LSTM(input_dim, hidden_dim, num_layers=2, batch_first=True) 41 | self.fc = nn.Linear(hidden_dim, output_dim) 42 | 43 | def forward(self, x): 44 | h0 = torch.zeros(2, x.size(0), self.hidden_dim).to(x.device) 45 | c0 = torch.zeros(2, x.size(0), self.hidden_dim).to(x.device) 46 | out, _ = self.rnn(x, (h0, c0)) 47 | out = self.fc(out[:, -1, :]) 48 | return out 49 | 50 | class Model: 51 | def __init__(self, input_dim, hidden_dim, output_dim, learning_rate, model_type): 52 | if model_type == 'nn': 53 | self.model = NeuralNetwork(input_dim, hidden_dim, output_dim) 54 | elif model_type == 'cnn': 55 | self.model = ConvolutionalNeuralNetwork(input_dim, hidden_dim, output_dim) 56 | elif model_type == 'rnn': 57 | self.model = RecurrentNeuralNetwork(input_dim, hidden_dim, output_dim) 58 | self.criterion = nn.CrossEntropyLoss() 59 | self.optimizer = optim.Adam(self.model.parameters(), lr=learning_rate) 60 | 61 | def train(self, X_train, y_train): 62 | self.model.train() 63 | self.optimizer.zero_grad() 64 | outputs = self.model(X_train) 65 | loss = self.criterion(outputs, y_train) 66 | loss.backward() 67 | self.optimizer.step() 68 | 69 | def evaluate(self, X_test, y_test): 70 | self.model.eval() 71 | outputs = self.model(X_test) 72 | _, predicted = torch.max(outputs, 1) 73 | return predicted 74 | 75 | def predict(self, X_test): 76 | self.model.eval() 77 | outputs = self.model(X_test) 78 | _, predicted = torch.max(outputs, 1) 79 | return predicted 80 | 81 | def evaluate_metrics(self, y_pred, y_test): 82 | accuracy = accuracy_score(y_test, y_pred) 83 | report = classification_report(y_test, y_pred) 84 | matrix = confusion_matrix(y_test, y_pred) 85 | return accuracy, report, matrix 86 | -------------------------------------------------------------------------------- /sdk/tools/cli_tool.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import json 3 | from sdk.libraries.crypto_library import CryptoLibrary 4 | 5 | class CliTool: 6 | def __init__(self): 7 | self.crypto_lib = CryptoLibrary() 8 | 9 | def generate_key_pair(self): 10 | # Generate a new RSA key pair 11 | key_pair = self.crypto_lib.generate_key_pair() 12 | private_key = key_pair.private_bytes( 13 | encoding=serialization.Encoding.PEM, 14 | format=serialization.PrivateFormat.PKCS8, 15 | encryption_algorithm=serialization.NoEncryption() 16 | ) 17 | public_key = key_pair.public_key().public_bytes( 18 | encoding=serialization.Encoding.OpenSSH, 19 | format=serialization.PublicFormat.OpenSSH 20 | ) 21 | print(f"Private Key: {private_key.decode('utf-8')}") 22 | print(f"Public Key: {public_key.decode('utf-8')}") 23 | 24 | def sign_data(self, private_key, data): 25 | # Sign data using a private key 26 | signature = self.crypto_lib.sign_data(private_key, data.encode('utf-8')) 27 | print(f"Signature: {signature.hex()}") 28 | 29 | def verify_signature(self, public_key, data, signature): 30 | # Verify a signature using a public key 31 | verified = self.crypto_lib.verify_signature(public_key, data.encode('utf-8'), signature) 32 | print(f"Verified: {verified}") 33 | 34 | def encrypt_data(self, public_key, data): 35 | # Encrypt data using a public key 36 | cipher_text = self.crypto_lib.encrypt_data(public_key, data.encode('utf-8')) 37 | print(f"Cipher Text: {cipher_text.hex()}") 38 | 39 | def decrypt_data(self, private_key, cipher_text): 40 | # Decrypt data using a private key 41 | plain_text = self.crypto_lib.decrypt_data(private_key, cipher_text) 42 | print(f"Plain Text: {plain_text.decode('utf-8')}") 43 | 44 | def main(): 45 | parser = argparse.ArgumentParser(description="CLI Tool for SDK") 46 | subparsers = parser.add_subparsers(dest="command") 47 | 48 | generate_key_pair_parser = subparsers.add_parser("generate-key-pair", help="Generate a new RSA key pair") 49 | generate_key_pair_parser.set_defaults(func=generate_key_pair) 50 | 51 | sign_data_parser = subparsers.add_parser("sign-data", help="Sign data using a private key") 52 | sign_data_parser.add_argument("private_key", help="Private key") 53 | sign_data_parser.add_argument("data", help="Data to sign") 54 | sign_data_parser.set_defaults(func=sign_data) 55 | 56 | verify_signature_parser = subparsers.add_parser("verify-signature", help="Verify a signature using a public key") 57 | verify_signature_parser.add_argument("public_key", help="Public key") 58 | verify_signature_parser.add_argument("data", help="Data to verify") 59 | verify_signature_parser.add_argument("signature", help="Signature to verify") 60 | verify_signature_parser.set_defaults(func=verify_signature) 61 | 62 | encrypt_data_parser = subparsers.add_parser("encrypt-data", help="Encrypt data using a public key") 63 | encrypt_data_parser.add_argument("public_key", help="Public key") 64 | encrypt_data_parser.add_argument("data", help="Data to encrypt") 65 | encrypt_data_parser.set_defaults(func=encrypt_data) 66 | 67 | decrypt_data_parser = subparsers.add_parser("decrypt-data", help="Decrypt data using a private key") 68 | decrypt_data_parser.add_argument("private_key", help="Private key") 69 | decrypt_data_parser.add_argument("cipher_text", help="Cipher text to decrypt") 70 | decrypt_data_parser.set_defaults(func=decrypt_data) 71 | 72 | args = parser.parse_args() 73 | cli_tool = CliTool() 74 | args.func(cli_tool, args) 75 | 76 | if __name__ == "__main__": 77 | main() 78 | -------------------------------------------------------------------------------- /blockchain/contracts/EcoPulseDAO.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol"; 4 | import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/utils/Address.sol"; 5 | 6 | contract EcoPulseDAO { 7 | // DAO details 8 | string public name = "EcoPulse DAO"; 9 | string public symbol = "EPDAO"; 10 | 11 | // Mapping of proposals 12 | mapping (uint256 => Proposal) public proposals; 13 | 14 | // Mapping of votes 15 | mapping (address => mapping (uint256 => bool)) public votes; 16 | 17 | // Event emitted when a new proposal is created 18 | event NewProposal(uint256 indexed proposalId, address indexed proposer, string description); 19 | 20 | // Event emitted when a proposal is voted on 21 | event Vote(uint256 indexed proposalId, address indexed voter, bool vote); 22 | 23 | // Event emitted when a proposal is executed 24 | event ExecuteProposal(uint256 indexed proposalId, address indexed executor); 25 | 26 | // Event emitted when a proposal is cancelled 27 | event CancelProposal(uint256 indexed proposalId, address indexed canceller); 28 | 29 | // Proposal struct 30 | struct Proposal { 31 | uint256 id; 32 | address proposer; 33 | string description; 34 | uint256 yesVotes; 35 | uint256 noVotes; 36 | bool executed; 37 | } 38 | 39 | // Proposal counter 40 | uint256 public proposalCounter = 0; 41 | 42 | // Constructor 43 | constructor() public { 44 | // Initialize DAO treasury 45 | treasury = address(this); 46 | } 47 | 48 | // Create a new proposal 49 | function newProposal(string memory description) public returns (uint256) { 50 | require(msg.sender != address(0), "Invalid proposer"); 51 | uint256 proposalId = proposalCounter++; 52 | proposals[proposalId] = Proposal(proposalId, msg.sender, description, 0, 0, false); 53 | emit NewProposal(proposalId, msg.sender, description); 54 | return proposalId; 55 | } 56 | 57 | // Vote on a proposal 58 | function vote(uint256 proposalId, bool vote) public { 59 | require(proposals[proposalId].proposer != address(0), "Invalid proposal"); 60 | require(!votes[msg.sender][proposalId], "Already voted"); 61 | if (vote) { 62 | proposals[proposalId].yesVotes++; 63 | } else { 64 | proposals[proposalId].noVotes++; 65 | } 66 | votes[msg.sender][proposalId] = true; 67 | emit Vote(proposalId, msg.sender, vote); 68 | } 69 | 70 | // Execute a proposal 71 | function executeProposal(uint256 proposalId) public { 72 | require(proposals[proposalId].proposer != address(0), "Invalid proposal"); 73 | require(!proposals[proposalId].executed, "Already executed"); 74 | require(proposals[proposalId].yesVotes > proposals[proposalId].noVotes, "Proposal not approved"); 75 | // Execute the proposal logic here 76 | proposals[proposalId].executed = true; 77 | emit ExecuteProposal(proposalId, msg.sender); 78 | } 79 | 80 | // Cancel a proposal 81 | function cancelProposal(uint256 proposalId) public { 82 | require(proposals[proposalId].proposer != address(0), "Invalid proposal"); 83 | require(!proposals[proposalId].executed, "Already executed"); 84 | delete proposals[proposalId]; 85 | emit CancelProposal(proposalId, msg.sender); 86 | } 87 | 88 | // Get proposal details 89 | function getProposal(uint256 proposalId) public view returns (Proposal memory) { 90 | return proposals[proposalId]; 91 | } 92 | 93 | // Get vote details 94 | function getVote(uint256 proposalId, address voter) public view returns (bool) { 95 | return votes[voter][proposalId]; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ai-engine/models/data.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | from sklearn.model_selection import train_test_split 4 | from sklearn.preprocessing import StandardScaler, LabelEncoder 5 | from sklearn.metrics import accuracy_score, classification_report, confusion_matrix 6 | from sklearn.impute import SimpleImputer 7 | from sklearn.compose import ColumnTransformer 8 | from sklearn.pipeline import Pipeline 9 | from sklearn.decomposition import PCA 10 | from sklearn.manifold import TSNE 11 | import matplotlib.pyplot as plt 12 | import seaborn as sns 13 | import plotly.express as px 14 | import plotly.graph_objects as go 15 | from plotly.offline import iplot 16 | from sklearn.feature_selection import SelectKBest, chi2 17 | from sklearn.ensemble import RandomForestClassifier 18 | from sklearn.model_selection import GridSearchCV 19 | from sklearn.metrics import roc_auc_score, f1_score, precision_score, recall_score 20 | from sklearn.utils.class_weight import compute_class_weight 21 | from imblearn.over_sampling import SMOTE 22 | from imblearn.under_sampling import RandomUnderSampler 23 | from imblearn.pipeline import Pipeline as ImbPipeline 24 | from collections import Counter 25 | 26 | class DataProcessor: 27 | def __init__(self, file_path): 28 | self.file_path = file_path 29 | self.data = pd.read_csv(file_path) 30 | 31 | def preprocess_data(self): 32 | # Handle missing values 33 | self.data.fillna(self.data.mean(), inplace=True) 34 | 35 | # Encode categorical variables 36 | categorical_cols = self.data.select_dtypes(include=['object']).columns 37 | for col in categorical_cols: 38 | le = LabelEncoder() 39 | self.data[col] = le.fit_transform(self.data[col]) 40 | 41 | # Scale numerical variables 42 | numerical_cols = self.data.select_dtypes(include=['int64', 'float64']).columns 43 | scaler = StandardScaler() 44 | self.data[numerical_cols] = scaler.fit_transform(self.data[numerical_cols]) 45 | 46 | # Feature selection 47 | X = self.data.drop('target', axis=1) 48 | y = self.data['target'] 49 | selector = SelectKBest(chi2, k=10) 50 | X_selected = selector.fit_transform(X, y) 51 | self.data = pd.concat((pd.DataFrame(X_selected), y), axis=1) 52 | 53 | return self.data 54 | 55 | def split_data(self, test_size=0.2, random_state=42): 56 | X = self.data.drop('target', axis=1) 57 | y = self.data['target'] 58 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=random_state) 59 | return X_train, X_test, y_train, y_test 60 | 61 | def evaluate_model(self, y_pred, y_test): 62 | accuracy = accuracy_score(y_test, y_pred) 63 | report = classification_report(y_test, y_pred) 64 | matrix = confusion_matrix(y_test, y_pred) 65 | return accuracy, report, matrix 66 | 67 | def visualize_data(self): 68 | # Correlation matrix 69 | corr_matrix = self.data.corr() 70 | plt.figure(figsize=(10, 8)) 71 | sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', square=True) 72 | plt.title('Correlation Matrix') 73 | plt.show() 74 | 75 | # PCA 76 | pca = PCA(n_components=2) 77 | X_pca = pca.fit_transform(self.data.drop('target', axis=1)) 78 | plt.figure(figsize=(8, 6)) 79 | sns.scatterplot(x=X_pca[:, 0], y=X_pca[:, 1], hue=self.data['target']) 80 | plt.title('PCA') 81 | plt.show() 82 | 83 | # t-SNE 84 | tsne = TSNE(n_components=2) 85 | X_tsne = tsne.fit_transform(self.data.drop('target', axis=1)) 86 | plt.figure(figsize=(8, 6)) 87 | sns.scatterplot(x=X_tsne[:, 0], y=X_tsne[:, 1], hue=self.data['target']) 88 | plt.title('t-SNE') 89 | plt.show() 90 | 91 | # Class distribution 92 | plt.figure(figsize=(8, 6)) 93 | sns.countplot(x=self.data['target']) 94 | plt.title('Class Distribution') 95 | plt.show() 96 | 97 | def handle_imbalance(self): 98 | X = self.data.drop('target', axis=1) 99 | y = self.data['target'] 100 | counter = Counter(y) 101 | print('Original class distribution:', counter) 102 | 103 | # Oversampling 104 | smote = SMOTE(random_state=42) 105 | X_res, y_res = smote.fit_resample(X, y) 106 | counter = Counter(y_res) 107 | print('Oversampled class distribution:', counter) 108 | 109 | # Undersampling 110 | rus = RandomUnderSampler(random_state=42) 111 | X_res, y_res = rus.fit_resample(X, y) 112 | counter = Counter(y_res) 113 | print('Undersampled class distribution:', counter) 114 | 115 | return X_res, y_res 116 | 117 | def feature_importance(self, X, y): 118 | 119 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------