<jupyter_start><jupyter_text>Psycellium: A Decentralized Cooperatives NetworkPsycellium is a blockchain network for cooperatives with the goal of bridging the gap between local communities and foster financial growth among its members. Services include loans, crowdfunding, and investments that can be done between registered cooperatives regardless of where they are. This opens a path for globalization and maximizing the utilization of blockchain in solving inter-border problems in transactions between communities.Draft Website (Not Complete): https://psycellium.herokuapp.com Github Link: https://github.com/kyleaquino/psycellium Note: Due to other important concerns I'm currently handling. I just developed a Minimum Viable Product Solution that introduces the fundamentals of how the platform should work.  The Code- Used python as my main programming language that will interact with the smart contract. - Used the Ethereum Libraries available for Python (Web3.py, solc) - Deployed the contract into the Ropsten Test Network<jupyter_code>import os
from web3 import Web3
from eth_account import Account
from solc import compile_files, compile_source
from web3.contract import ConciseContract<jupyter_output><empty_output><jupyter_text>This initialize the Ethereum node that will be used to connect with the ropsten etheruem test network via infuria<jupyter_code>def initWeb3():
    web3=Web3(Web3.HTTPProvider('https://ropsten.infura.io/v3/6c25a8476cd941aab5961e19adde9502'))
    print("Web3 is Conntected:", web3.isConnected())
    return web3<jupyter_output><empty_output><jupyter_text>This will be the general function for the creation of new ethereum wallets<jupyter_code>def createAccount(password):
    account = Account.create(password)
    return account, password<jupyter_output><empty_output><jupyter_text>This creates a new cooperative in the ethereum network, each contract represents a single cooperative, the contract address represents their id to verify the members and transactions facilitated inside the organization. The sender/deployer of the contract will be temporarily be the director of the cooperative to facilitate the transactions<jupyter_code>def createCoop(web3, name, description, account):
    # Deploy New Contract
    compiled_sol=compile_files(['contracts/Cooperatives.sol'])
    interface=compiled_sol['contracts/Cooperatives.sol:Cooperatives']
    contract=web3.eth.contract(abi=interface['abi'], bytecode=interface['bin'])
    
    # Prepare Transaction 
    txn = {
        'chainId': 3,
        'gas': contract.constructor(name, description).estimateGas()*2,
        'gasPrice': web3.toWei('1', 'gwei'),
        'nonce': web3.eth.getTransactionCount(account.address)
    }
    
    # Deploy Transaction
    deploy_txn=contract.constructor(name, description).buildTransaction(txn)
    signed=web3.eth.account.signTransaction(deploy_txn, account.privateKey)
    txn_hash=web3.eth.sendRawTransaction(signed.rawTransaction)  
    txn_receipt=web3.eth.waitForTransactionReceipt(txn_hash)
    contract = web3.eth.contract(address=txn_receipt.contractAddress,abi=contract.abi)
    
    print("HASH:", txn_hash)
    print("RECIEPT:", txn_receipt)
    return contract<jupyter_output><empty_output><jupyter_text>Anyone can join the cooperative deployed in the ethereum network the default registration fee is set to 200000000000000000 wei (around 25 USD) *Will add a functionality to change the fee requirement<jupyter_code>def joinCoop(web3, contract, sender, amount):
    txn = {
        'chainId': 3,
        'value': amount,
        'gasPrice': web3.toWei('1', 'gwei'),
        'nonce': web3.eth.getTransactionCount(sender.address)
    }
    txn['gas'] = 1000000
    print(txn['gas'])
    deploy_txn=contract.functions.joinCoop(amount).buildTransaction(txn)
    signed=web3.eth.account.signTransaction(deploy_txn, sender.privateKey)
    txn_hash=web3.eth.sendRawTransaction(signed.rawTransaction)  
    txn_receipt=web3.eth.waitForTransactionReceipt(txn_hash)
    print("HASH:", txn_hash)
    print("RECIEPT:", txn_receipt)<jupyter_output><empty_output><jupyter_text>This sets new directors in the cooperatives. The candidate must first be a cooperatives member to be eligible to become a director<jupyter_code>def setDirector(web3, contract, sender, member):
    txn = {
        'chainId': 3,
        'gas': contract.functions.setDirector(member.address).estimateGas()*2,
        'gasPrice': web3.toWei('1', 'gwei'),
        'nonce': web3.eth.getTransactionCount(sender.address)
    } 
    deploy_txn=contract.functions.setDirector(member.address).buildTransaction(txn)
    signed=web3.eth.account.signTransaction(deploy_txn, sender.privateKey)
    txn_hash=web3.eth.sendRawTransaction(signed.rawTransaction)  
    txn_receipt=web3.eth.waitForTransactionReceipt(txn_hash)
    print("HASH:", txn_hash)
    print("RECIEPT:", txn_receipt)<jupyter_output><empty_output><jupyter_text>Each member can deposit their funds into their cooperatives. The deposited amount will be stored into the contract address of the cooperatives and is recorded through the event logs. the benefits of choosing the cooperatives as their bank will be done offchain<jupyter_code>def deposit(web3, contract, sender, amount):
    txn = {
        'to': contract.address,
        'from': sender.address,
        'chainId': 3,
        'value': amount,
        'gas': contract.functions.deposit(amount).estimateGas()*2,
        'gasPrice': web3.toWei('1', 'gwei'),
        'nonce': web3.eth.getTransactionCount(sender.address)
    }
    deploy_txn=contract.functions.deposit(amount).buildTransaction(txn)
    signed=web3.eth.account.signTransaction(deploy_txn, sender.privateKey)
    txn_hash=web3.eth.sendRawTransaction(signed.rawTransaction)  
    txn_receipt=web3.eth.waitForTransactionReceipt(txn_hash)
    print("HASH:", txn_hash)
    print("RECIEPT:", txn_receipt)<jupyter_output><empty_output><jupyter_text>Each member is also free from withdrawing the amount they deposited<jupyter_code>def withdraw(web3, contract, sender, amount):
    txn = {
        'chainId': 3,
        'gas': contract.functions.withdraw(amount).estimateGas()*2,
        'gasPrice': web3.toWei('1', 'gwei'),
        'nonce': web3.eth.getTransactionCount(sender.address)
    }
    deploy_txn=contract.functions.withdraw(amount).buildTransaction(txn)
    signed=web3.eth.account.signTransaction(deploy_txn, sender.privateKey)
    txn_hash=web3.eth.sendRawTransaction(signed.rawTransaction)  
    txn_receipt=web3.eth.waitForTransactionReceipt(txn_hash)
    print("HASH:", txn_hash)
    print("RECIEPT:", txn_receipt)<jupyter_output><empty_output><jupyter_text>The cooperatives can transfer funds to another address by the approval of the directors<jupyter_code>def submitRequest(web3, contract, sender, destination, amount):
    txn = {
        'chainId': 3, 
        'gasPrice': web3.toWei('1', 'gwei'),
        'nonce': web3.eth.getTransactionCount(sender.address)
    }
    txn['gas'] = contract.functions.sumbitRequest(destination.address, amount, bytes(0)).estimateGas() #Fix 'Sumbit' Typo
    deploy_txn=contract.functions.sumbitRequest(destination.address, amount, bytes(0)).buildTransaction(txn) #Fix 'Sumbit' Typo
    signed=web3.eth.account.signTransaction(deploy_txn, sender.privateKey)
    txn_hash=web3.eth.sendRawTransaction(signed.rawTransaction)  
    txn_receipt=web3.eth.waitForTransactionReceipt(txn_hash)
    print("HASH:", txn_hash)
    print("RECIEPT:", txn_receipt)<jupyter_output><empty_output><jupyter_text>Only the directors can confirm the transaction. Once the confirmation is complete the funds are transfered to the destination address<jupyter_code>def confirmTransaction(web3, contract, sender, txn_id):
    txn = {
        'chainId': 3, 
        'gas': contract.functions.confirmTransaction(txn_id).estimateGas()*2,
        'gasPrice': web3.toWei('1', 'gwei'),
        'nonce': web3.eth.getTransactionCount(sender.address)
    }
    deploy_txn=contract.functions.confirmTransaction(txn_id).buildTransaction(txn)
    signed=web3.eth.account.signTransaction(deploy_txn, sender.privateKey)
    txn_hash=web3.eth.sendRawTransaction(signed.rawTransaction)  
    txn_receipt=web3.eth.waitForTransactionReceipt(txn_hash)
    print("HASH:", txn_hash)
    print("RECIEPT:", txn_receipt)<jupyter_output><empty_output><jupyter_text>Only the directors can revoke the transaction. This revokes the pending request<jupyter_code>def revokeTransaction(web3, contract, sender, txn_id):
    txn = {
        'chainId': 3, 
        'gas': contract.functions.revokeTransaction(txn_id).estimateGas()*2,
        'gasPrice': web3.toWei('1', 'gwei'),
        'nonce': web3.eth.getTransactionCount(sender.address)
    }
    deploy_txn=contract.functions.revokeTransaction(txn_id).buildTransaction(txn)
    signed=web3.eth.account.signTransaction(deploy_txn, sender.privateKey)
    txn_hash=web3.eth.sendRawTransaction(signed.rawTransaction)  
    txn_receipt=web3.eth.waitForTransactionReceipt(txn_hash)
    print("HASH:", txn_hash)
    print("RECIEPT:", txn_receipt)<jupyter_output><empty_output><jupyter_text>Demo This demo presents how the contract work and how it will integrate to the user interface 1. I created first the deployer of the contract which will be the temporary director of the cooperative<jupyter_code>web3=initWeb3()
account, password = createAccount('admin1234')
web3.eth.defaultAccount = account.address

print("Account:", account.address)
print("Private Key:", account.privateKey)<jupyter_output>True
Account: 0xF3e2DB0F694EC09D5546298fa7B801D37A3b45DF
Private Key: b'\<KEY>'<jupyter_text>2. I sent money from the metamask application using my other ethereum account at 0x1B3b63E30d666CEb1f26933Cb18869aB8e610265<jupyter_code>print('Account Balance:', web3.eth.getBalance(account.address))<jupyter_output>Account Balance: 100000000000000000<jupyter_text>This deploys the contract and sets the sender as the director of the contract<jupyter_code>contract = createCoop(web3, 'Psycellium','A Decentralized Cooperatives Network', account)
print('Cooperative Details')
print('ETH Address:', contract.address)
print('Name:', contract.functions.getCoopName().call())
print('Description:', contract.functions.getCoopDescription().call())
print('Funds:', web3.eth.getBalance(contract.address))
print('Members:', contract.functions.getCoopMembers().call())<jupyter_output>Cooperative Details
ETH Address: 0x9b022f8BcdbC0E9E117640da3E913a9bDE8FF20B
Name: Psycellium
Description: A Decentralized Cooperatives Network
Funds: 0
Members: ['0xF3e2DB0F694EC09D5546298fa7B801D37A3b45DF']<jupyter_text>Contract Functions<jupyter_code>concise_contract = ConciseContract(contract)
dir(concise_contract)<jupyter_output><empty_output><jupyter_text>Creating Accounts and Joining to the Cooperatives  Account 1<jupyter_code>account_1, password_1 = createAccount('account1')

print("Account:", account_1.address)
print("Password:", <PASSWORD>)
print("Private Key:", account_1.privateKey)
print('Account Balance:', web3.eth.getBalance(account_1.address))
joinCoop(web3, contract, account_1, 200000000000000000)
print('Cooperative Details After Account1 Joining')
print('ETH Address:', contract.address)
print('Name:', contract.functions.getCoopName().call())
print('Description:', contract.functions.getCoopDescription().call())
print('Funds:', web3.eth.getBalance(contract.address))
print('Members:', contract.functions.getCoopMembers().call())<jupyter_output>Cooperative Details After Account1 Joining
ETH Address: 0x9b022f8BcdbC0E9E117640da3E913a9bDE8FF20B
Name: Psycellium
Description: A Decentralized Cooperatives Network
Funds: 200000000000000000
Members: ['0xF<KEY>', '0x89253625f17B96dfE9fFbF69593B261Fa5ca89aB']<jupyter_text>Account 2<jupyter_code>account_2, password_2 = createAccount('account2')

print("Account:", account_2.address)
print("Password:", <PASSWORD>)
print("Private Key:", account_2.privateKey)
print('Account Balance:', web3.eth.getBalance(account_2.address))
joinCoop(web3, contract, account_2, 200000000000000000)
print('Cooperative Details After Account2 Joining')
print('ETH Address:', contract.address)
print('Name:', contract.functions.getCoopName().call())
print('Description:', contract.functions.getCoopDescription().call())
print('Funds:', web3.eth.getBalance(contract.address))
print('Members:', contract.functions.getCoopMembers().call())<jupyter_output>Cooperative Details After Account2 Joining
ETH Address: 0x9b022f8BcdbC0E9E117640da3E913a9bDE8FF20B
Name: Psycellium
Description: A Decentralized Cooperatives Network
Funds: 400000000000000000
Members: ['0xF3e2DB0F694EC09D5546298fa7B801D37A3b45DF', '<KEY>', '0x5e7375676C1C8A94B957CA370243FEa737247d46']<jupyter_text>Account 3<jupyter_code>account_3, password_3 = createAccount('account1')

print("Account:", account_3.address)
print("Password:", password_3)
print("Private Key:", account_3.privateKey)
print('Account Balance:', web3.eth.getBalance(account_3.address))
joinCoop(web3, contract, account_3, 200000000000000000)
print('Cooperative Details After Account3 Joining')
print('ETH Address:', contract.address)
print('Name:', contract.functions.getCoopName().call())
print('Description:', contract.functions.getCoopDescription().call())
print('Funds:', web3.eth.getBalance(contract.address))
print('Members:', contract.functions.getCoopMembers().call())<jupyter_output>Cooperative Details After Account3 Joining
ETH Address: 0x9b022f8BcdbC0E9E117640da3E913a9bDE8FF20B
Name: Psycellium
Description: A Decentralized Cooperatives Network
Funds: 600000000000000000
Members: ['0xF<KEY>', '0x89253625f17B96dfE9fFbF69593B261Fa5ca89aB', '0x5e7375676C1C8A94B957CA370243FEa737247d46', '0x443b9E6354180f20aE7c453b22f6e8c1BD8cA52d']<jupyter_text>Set New Director<jupyter_code>setDirector(web3, contract, account, account_1)
print('Directors:', contract.functions.getDirectors().call())<jupyter_output>Directors: ['0xF3e2DB0F694EC09D5546298fa7B801D37A3b45DF', '0x89253625f17B96dfE9fFbF69593B261Fa5ca89aB']<jupyter_text>Submit Request<jupyter_code>submitRequest(web3, contract, account, account_3, 200000000000000000)
print('Account Balance:', web3.eth.getBalance(account_3.address))
print('Funds:', web3.eth.getBalance(contract.address))<jupyter_output>Funds: 400000000000000000
{'fraction_non_alphanumeric': 0.10768906973481128, 'fraction_numerical': 0.0514943173845938, 'mean_word_length': 6.610784837159637, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 79, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 10, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '20', 'dir': 'jupyter-structured-clean-dedup', 'id': '180410', 'license': 'MIT', 'n_tokens_mistral': 5040, 'n_tokens_neox': 4578, 'n_words': 912, 'path': 'ethereum/Demo.ipynb', 'repo_name': 'kyleaquino/psycellium', 'size': '14448'}