├── docs ├── CNAME ├── favicon.ico ├── img │ └── horseAnatomy.jpg ├── static │ └── css │ │ ├── main.8eded250.css.map │ │ └── main.8eded250.css ├── asset-manifest.json └── index.html ├── public ├── favicon.ico ├── img │ └── horseAnatomy.jpg └── index.html ├── src ├── fonts │ ├── Oswald-300 │ │ ├── Oswald-300.eot │ │ ├── Oswald-300.ttf │ │ ├── Oswald-300.woff │ │ ├── Oswald-300.woff2 │ │ └── LICENSE.txt │ ├── Oswald-regular │ │ ├── Oswald-regular.eot │ │ ├── Oswald-regular.ttf │ │ ├── Oswald-regular.woff │ │ ├── Oswald-regular.woff2 │ │ └── LICENSE.txt │ └── Open-Sans-regular │ │ ├── Open-Sans-regular.eot │ │ ├── Open-Sans-regular.ttf │ │ ├── Open-Sans-regular.woff │ │ ├── Open-Sans-regular.woff2 │ │ └── LICENSE.txt ├── App.test.js ├── index.js ├── index.css ├── css │ ├── open-sans.css │ └── oswald.css ├── Warning.js ├── MarkdownLoader.js ├── GreyTheme.js ├── LandingPage.md ├── ProjectCard.js ├── UnconfirmedProjectCard.js ├── App.css ├── UnconfirmedProposalCard.js ├── CreateProjectPage.js ├── ProjectsListPage.js ├── Page.js ├── CreateProposalPage.js ├── ProjectOverview.js ├── LandingPage.js ├── ProjectsList.js ├── ProposalChart.js ├── ProposalsList.js ├── NetworkState.js ├── ProjectPage.js ├── App.js ├── State.js ├── OwnershipChart.js ├── Web3AutoSetup.js └── ProposalCard.js ├── migrations ├── 2_deploy_contracts.js └── 1_initial_migration.js ├── config ├── jest │ ├── fileTransform.js │ └── cssTransform.js ├── polyfills.js ├── env.js ├── paths.js ├── webpack.config.dev.js └── webpack.config.prod.js ├── .gitignore ├── test ├── TestUumm.sol ├── VotingData.js ├── Funding.js ├── Validators.js └── Voting.js ├── support ├── Contracts definitions.md ├── Context.md ├── ContractStructure ├── DeconstructionGovernanceExamples.js ├── Merit Examples.md ├── Interoperable Adhocracy.md ├── Reputation for governance.md └── UxFlowDiagram.xml ├── truffle-config.js ├── contracts └── Migrations.sol ├── scripts ├── test.js └── build.js ├── contributors.md ├── DeconstructionGovernanceExamples.js ├── package.json └── README.md /docs/CNAME: -------------------------------------------------------------------------------- 1 | uumm.io -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /docs/img/horseAnatomy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/docs/img/horseAnatomy.jpg -------------------------------------------------------------------------------- /public/img/horseAnatomy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/public/img/horseAnatomy.jpg -------------------------------------------------------------------------------- /src/fonts/Oswald-300/Oswald-300.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Oswald-300/Oswald-300.eot -------------------------------------------------------------------------------- /src/fonts/Oswald-300/Oswald-300.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Oswald-300/Oswald-300.ttf -------------------------------------------------------------------------------- /src/fonts/Oswald-300/Oswald-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Oswald-300/Oswald-300.woff -------------------------------------------------------------------------------- /src/fonts/Oswald-300/Oswald-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Oswald-300/Oswald-300.woff2 -------------------------------------------------------------------------------- /docs/static/css/main.8eded250.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":[],"names":[],"mappings":"","file":"static/css/main.8eded250.css","sourceRoot":""} -------------------------------------------------------------------------------- /src/fonts/Oswald-regular/Oswald-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Oswald-regular/Oswald-regular.eot -------------------------------------------------------------------------------- /src/fonts/Oswald-regular/Oswald-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Oswald-regular/Oswald-regular.ttf -------------------------------------------------------------------------------- /src/fonts/Oswald-regular/Oswald-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Oswald-regular/Oswald-regular.woff -------------------------------------------------------------------------------- /src/fonts/Oswald-regular/Oswald-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Oswald-regular/Oswald-regular.woff2 -------------------------------------------------------------------------------- /src/fonts/Open-Sans-regular/Open-Sans-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Open-Sans-regular/Open-Sans-regular.eot -------------------------------------------------------------------------------- /src/fonts/Open-Sans-regular/Open-Sans-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Open-Sans-regular/Open-Sans-regular.ttf -------------------------------------------------------------------------------- /src/fonts/Open-Sans-regular/Open-Sans-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Open-Sans-regular/Open-Sans-regular.woff -------------------------------------------------------------------------------- /migrations/2_deploy_contracts.js: -------------------------------------------------------------------------------- 1 | var uumm = artifacts.require("./uumm.sol"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(uumm); 5 | }; 6 | -------------------------------------------------------------------------------- /src/fonts/Open-Sans-regular/Open-Sans-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UummProject/uumm-prototype/HEAD/src/fonts/Open-Sans-regular/Open-Sans-regular.woff2 -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("./Migrations.sol"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /docs/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "main.css": "static/css/main.8eded250.css", 3 | "main.css.map": "static/css/main.8eded250.css.map", 4 | "main.js": "static/js/main.6b1785f9.js", 5 | "main.js.map": "static/js/main.6b1785f9.js.map" 6 | } -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | }); 9 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | //import truffleConfig from './../truffle-config.js' 6 | 7 | ReactDOM.render( 8 | , 9 | document.getElementById('root') 10 | ); 11 | -------------------------------------------------------------------------------- /docs/static/css/main.8eded250.css: -------------------------------------------------------------------------------- 1 | body{margin:0;padding:0;font-family:Open Sans,sans-serif;height:100%;background-color:#f8f7f5}h1,h2,h3,h4,h5,h6{font-weight:300}p{margin-top:10px;margin-bottom:10px}.markdown{color:#666}.markdown img{width:100%}a{text-decoration:none}a:link,a:visited{color:#f36}a:hover{color:red} 2 | /*# sourceMappingURL=main.8eded250.css.map*/ -------------------------------------------------------------------------------- /config/jest/fileTransform.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | // This is a custom Jest transformer turning file imports into filenames. 4 | // http://facebook.github.io/jest/docs/tutorial-webpack.html 5 | 6 | module.exports = { 7 | process(src, filename) { 8 | return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'; 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # testing 7 | coverage 8 | 9 | # production 10 | build 11 | build_webpack 12 | 13 | # misc 14 | .DS_Store 15 | .env 16 | npm-debug.log 17 | .truffle-solidity-loader 18 | notes.md 19 | Goverment 20 | horseAnatomy.psd 21 | bottlenecks.md 22 | -------------------------------------------------------------------------------- /config/jest/cssTransform.js: -------------------------------------------------------------------------------- 1 | // This is a custom Jest transformer turning style imports into empty objects. 2 | // http://facebook.github.io/jest/docs/tutorial-webpack.html 3 | 4 | module.exports = { 5 | process() { 6 | return 'module.exports = {};'; 7 | }, 8 | getCacheKey(fileData, filename) { 9 | // The output is always the same. 10 | return 'cssTransform'; 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /test/TestUumm.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.11; 2 | 3 | import "truffle/Assert.sol"; 4 | import "truffle/DeployedAddresses.sol"; 5 | import "../contracts/Uumm.sol"; 6 | 7 | contract TestUumm 8 | { 9 | function testFunction() 10 | { 11 | //Uumm uumm = Uumm(DeployedAddresses.Uumm()); 12 | //uint256 expected = 2; 13 | //Assert.equal( 2, expected, "It should return the sha3 of the address + the nonce"); 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /support/Contracts definitions.md: -------------------------------------------------------------------------------- 1 | #Contracts 2 | 3 | ##Intro contract 4 | - Is the access point to the platform. 5 | - Has access to a registry of the projects associated to each user 6 | - Deploys all the contracts that will form a project 7 | 8 | 9 | ##Proxy contract 10 | - It routes contract ids to addresses 11 | - It allows to replace contracts 12 | 13 | ##Governance contract 14 | - Handles the voting 15 | - Has a merit contract associated 16 | 17 | ##Merit contract 18 | - Defines the voting rights of each entity 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0px; 3 | padding: 0px; 4 | font-family: 'Open Sans', sans-serif; 5 | height:100%; 6 | background-color: #F8F7F5; 7 | } 8 | 9 | h1,h2,h3,h4,h5,h6 { 10 | font-weight: 300; 11 | } 12 | 13 | p { 14 | margin-top: 10px; 15 | margin-bottom: 10px; 16 | } 17 | 18 | 19 | .markdown { 20 | color:#666666; 21 | } 22 | .markdown img { 23 | width:100%; 24 | } 25 | 26 | a{ 27 | text-decoration: none 28 | } 29 | a:link { 30 | color: #ff3366; 31 | } 32 | 33 | a:visited { 34 | color: #ff3366; 35 | } 36 | 37 | a:hover { 38 | color: red; 39 | } 40 | -------------------------------------------------------------------------------- /truffle-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | migrations_directory: "./migrations", 3 | networks: { 4 | development: { 5 | host: "localhost", 6 | port: 8546, 7 | network_id: "*" // Match any network id 8 | }, 9 | ropsten: { 10 | host: "localhost", 11 | port: 8545, 12 | gas: 461288, //if to big fails 13 | network_id: "3" 14 | }, 15 | //When "npm start build", process.env.NODE_ENV == production 16 | production: { 17 | host: "localhost", 18 | port: 8545, 19 | gas: 4612388, 20 | network_id: "3" 21 | } 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.11; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | modifier restricted() { 8 | if (msg.sender == owner) _; 9 | } 10 | 11 | function Migrations() public { 12 | owner = msg.sender; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } -------------------------------------------------------------------------------- /config/polyfills.js: -------------------------------------------------------------------------------- 1 | if (typeof Promise === 'undefined') { 2 | // Rejection tracking prevents a common issue where React gets into an 3 | // inconsistent state due to an error, but it gets swallowed by a Promise, 4 | // and the user has no idea what causes React's erratic future behavior. 5 | require('promise/lib/rejection-tracking').enable(); 6 | window.Promise = require('promise/lib/es6-extensions.js'); 7 | } 8 | 9 | // fetch() polyfill for making API calls. 10 | require('whatwg-fetch'); 11 | 12 | // Object.assign() is commonly used with React. 13 | // It will use the native implementation if it's present and isn't buggy. 14 | Object.assign = require('object-assign'); 15 | -------------------------------------------------------------------------------- /src/css/open-sans.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Open Sans'; 3 | font-weight: 400; 4 | font-style: normal; 5 | src: url('../fonts/Open-Sans-regular/Open-Sans-regular.eot'); 6 | src: url('../fonts/Open-Sans-regular/Open-Sans-regular.eot?#iefix') format('embedded-opentype'), 7 | local('Open Sans'), 8 | local('Open-Sans-regular'), 9 | url('../fonts/Open-Sans-regular/Open-Sans-regular.woff2') format('woff2'), 10 | url('../fonts/Open-Sans-regular/Open-Sans-regular.woff') format('woff'), 11 | url('../fonts/Open-Sans-regular/Open-Sans-regular.ttf') format('truetype'), 12 | url('../fonts/Open-Sans-regular/Open-Sans-regular.svg#OpenSans') format('svg'); 13 | } 14 | -------------------------------------------------------------------------------- /src/Warning.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class Warning extends Component 4 | { 5 | render(){ 6 | 7 | let style = { 8 | backgroundColor:'rgba(158, 158, 158, 0.22)', 9 | paddingTop:10, 10 | paddingBottom:10, 11 | paddingLeft:20, 12 | paddingRight:20, 13 | marginBottom:20 14 | } 15 | 16 | if(this.props.important) 17 | style.backgroundColor = 'rgba(158, 0, 0, 0.22)' 18 | 19 | return ( 20 |
21 | {this.props.children} 22 |
23 | ) 24 | } 25 | } 26 | 27 | export default Warning 28 | -------------------------------------------------------------------------------- /src/MarkdownLoader.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Axios from 'axios' 3 | import ReactMarkdown from'react-markdown' 4 | 5 | class MarkdownLoader extends React.Component { 6 | 7 | constructor(props) 8 | { 9 | super() 10 | 11 | this.state = {markdownText:""} 12 | 13 | if(props.url) 14 | Axios.get(props.url) 15 | .then((result)=> { 16 | this.setState({markdownText:result.data}) 17 | }); 18 | } 19 | 20 | 21 | render() 22 | { 23 | return ( 24 |
25 | 26 |
27 | ) 28 | } 29 | } 30 | 31 | export default MarkdownLoader -------------------------------------------------------------------------------- /src/GreyTheme.js: -------------------------------------------------------------------------------- 1 | import getMuiTheme from 'material-ui/styles/getMuiTheme'; 2 | import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme'; 3 | //using https://cimdalli.github.io/mui-theme-generator/ 4 | 5 | const getTheme = () => { 6 | let overwrites = { 7 | "fontFamily": "Open Sans Condensed, sans-serif", 8 | "palette": { 9 | "primary1Color": "rgba(0, 0, 0, 0.49)", 10 | "accent1Color": "rgba(0, 0, 0, 0.87)", 11 | "canvasColor": "#F8F7F5" 12 | }, 13 | "tabs": { 14 | "backgroundColor": "#F8F7F5", 15 | "textColor": "rgba(0, 0, 0, 0.54)", 16 | "selectedTextColor": "#424242" 17 | } 18 | } 19 | //console.log(JSON.stringify(overwrites)) 20 | 21 | return getMuiTheme(baseTheme, overwrites); 22 | } 23 | 24 | export default getTheme() -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | Uumm
-------------------------------------------------------------------------------- /src/LandingPage.md: -------------------------------------------------------------------------------- 1 | # What is this 2 | 3 | In recent years a new paradigm around decentralization has emerged. 4 | Technologies such as [Ethereum](https://www.ethereum.org/), [IPFS](https://ipfs.io/) or [Bitcoin](https://en.wikipedia.org/wiki/Bitcoin) offer a new set of possibilities for re-designing most of the systems that drive our society. 5 | 6 | Uumm is an open-source, experimental tool, for the process of decision making build on top of these new exciting technologies. 7 | 8 | # Where are we 9 | We have a first working prototype. On the [Github repo](https://github.com/xavivives/uumm) you can find all the details about it. 10 | 11 | We're already [designing the next iteration](https://github.com/xavivives/Uumm/blob/master/support/Broken%20meritocracy.md), while keep polishing this one. 12 | 13 | [Follow us on twitter](https://twitter.com/xavivives), to stay up to date. -------------------------------------------------------------------------------- /src/ProjectCard.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const containerStyle = 4 | { 5 | display: 'flex', 6 | flexDirection: 'row', 7 | flexWrap: 'nowrap', 8 | justifyContent: 'space-between', 9 | alignItems: 'center', 10 | height : 60, 11 | minWidth:600 12 | } 13 | 14 | const titleStyle = 15 | { 16 | display: 'flex', 17 | flexDirection: 'column', 18 | justifyContent: 'center', 19 | alignItems: 'flexStart', 20 | flexGrow: 4, 21 | fontWeight: 300 22 | } 23 | 24 | class ProjectCard extends React.Component { 25 | 26 | constructor(props) 27 | { 28 | super(); 29 | } 30 | 31 | onTouchTap =() => 32 | { 33 | this.props.onTouchTap(this.props.data) 34 | } 35 | 36 | render() 37 | { 38 | return ( 39 |
40 |

{this.props.data.name}

41 |
42 | ); 43 | } 44 | } 45 | 46 | export default ProjectCard; -------------------------------------------------------------------------------- /src/UnconfirmedProjectCard.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const containerStyle = 4 | { 5 | display: 'flex', 6 | flexDirection: 'row', 7 | flexWrap: 'nowrap', 8 | justifyContent: 'space-between', 9 | alignItems: 'center', 10 | height : 60, 11 | minWidth:600 12 | } 13 | 14 | const titleStyle = 15 | { 16 | display: 'flex', 17 | flexDirection: 'column', 18 | justifyContent: 'center', 19 | alignItems: 'flexStart', 20 | flexGrow: 4, 21 | fontWeight: 300 22 | } 23 | class UnconfirmedProjectCard extends React.Component { 24 | 25 | constructor(props) 26 | { 27 | super(); 28 | } 29 | 30 | render() 31 | { 32 | return ( 33 |
34 |

{this.props.data.name}

35 |

unconfirmed

36 |
37 | ); 38 | } 39 | } 40 | 41 | export default UnconfirmedProjectCard; -------------------------------------------------------------------------------- /scripts/test.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = 'test'; 2 | process.env.PUBLIC_URL = ''; 3 | 4 | // Load environment variables from .env file. Suppress warnings using silent 5 | // if this file is missing. dotenv will never modify any environment variables 6 | // that have already been set. 7 | // https://github.com/motdotla/dotenv 8 | require('dotenv').config({silent: true}); 9 | 10 | const jest = require('jest'); 11 | const argv = process.argv.slice(2); 12 | 13 | // Watch unless on CI or in coverage mode 14 | if (!process.env.CI && argv.indexOf('--coverage') < 0) { 15 | argv.push('--watch'); 16 | } 17 | 18 | // A temporary hack to clear terminal correctly. 19 | // You can remove this after updating to Jest 18 when it's out. 20 | // https://github.com/facebook/jest/pull/2230 21 | var realWrite = process.stdout.write; 22 | var CLEAR = process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H'; 23 | process.stdout.write = function(chunk, encoding, callback) { 24 | if (chunk === '\x1B[2J\x1B[H') { 25 | chunk = CLEAR; 26 | } 27 | return realWrite.call(this, chunk, encoding, callback); 28 | }; 29 | 30 | 31 | jest.run(argv); 32 | -------------------------------------------------------------------------------- /support/Context.md: -------------------------------------------------------------------------------- 1 | 2 | _This is a live document, any feedback to improved it will be highly appreciated._ 3 | 4 | ### Context 5 | In recent years a new paradigm around decentralization has emerged. 6 | technologies such as [Ethereum](https://www.ethereum.org/), [IPFS](https://ipfs.io/) or [Bitcoin](https://en.wikipedia.org/wiki/Bitcoin) offer a new set of possibilities for re-designing most of the systems that drive our society. 7 | 8 | _Governance_ has been echoing within the community for long time. And for good reason. The abscence of a central authority seems to imply no-governance. Whatever this is true or not governance, issues have been all over the place. 9 | 10 | ### Motivations 11 | As part of the [Uumm](https://xavivives.github.io/Uumm/#intro) project I wanted to distill _governance_, to later put it together in some sort of tool with full consideration of this new paradigm. It was personal exercice to better understand how the future of governance may look like. 12 | 13 | This document is an attempt to imagine and lay down the fundamental pieces on how future organizations build ont top of this new paradigmn may look like. 14 | 15 | -------------------------------------------------------------------------------- /config/env.js: -------------------------------------------------------------------------------- 1 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be 2 | // injected into the application via DefinePlugin in Webpack configuration. 3 | 4 | var REACT_APP = /^REACT_APP_/i; 5 | 6 | function getClientEnvironment(publicUrl) { 7 | var processEnv = Object 8 | .keys(process.env) 9 | .filter(key => REACT_APP.test(key)) 10 | .reduce((env, key) => { 11 | env[key] = JSON.stringify(process.env[key]); 12 | return env; 13 | }, { 14 | // Useful for determining whether we’re running in production mode. 15 | // Most importantly, it switches React into the correct mode. 16 | 'NODE_ENV': JSON.stringify( 17 | process.env.NODE_ENV || 'development' 18 | ), 19 | // Useful for resolving the correct path to static assets in `public`. 20 | // For example, . 21 | // This should only be used as an escape hatch. Normally you would put 22 | // images into the `src` and `import` them in code to get their paths. 23 | 'PUBLIC_URL': JSON.stringify(publicUrl) 24 | }); 25 | return {'process.env': processEnv}; 26 | } 27 | 28 | module.exports = getClientEnvironment; 29 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | /* PAGE */ 2 | 3 | body, 4 | .pure-g [class*=pure-u] { 5 | font-family: 'Open Sans', sans-serif; 6 | } 7 | 8 | h1, h2, h3 { 9 | font-family: 'Oswald', 'Arial Narrow', sans-serif; 10 | } 11 | 12 | code { 13 | display: block; 14 | margin: 20px 0 15px 0; 15 | padding: 10px; 16 | background: #eee; 17 | } 18 | 19 | .container { 20 | box-sizing: border-box; 21 | width: 100%; 22 | padding: 45px 20px; 23 | } 24 | 25 | .pure-button-primary { 26 | background-color: #0c1a2b; 27 | } 28 | 29 | .pure-button-primary:hover { 30 | background-color: #233e5e; 31 | } 32 | 33 | .pure-form input[type="text"]:focus { 34 | border-color: #0c1a2b; 35 | } 36 | 37 | /* NAVBAR */ 38 | 39 | .navbar { 40 | position: fixed; 41 | padding: 5px; 42 | background: #0c1a2b; 43 | font-family: 'Oswald', 'Arial Narrow', sans-serif; 44 | } 45 | 46 | .navbar a { 47 | color: #fff; 48 | } 49 | 50 | .navbar a:active, 51 | .navbar a:focus, 52 | .navbar a:hover { 53 | background: #233e5e; 54 | } 55 | 56 | .navbar .pure-menu-heading { 57 | font-weight: bold; 58 | text-transform: none; 59 | } 60 | 61 | .navbar .navbar-right { 62 | float: right; 63 | } 64 | 65 | .navbar .uport-logo { 66 | height: 16px; 67 | margin-right: 10px; 68 | } 69 | -------------------------------------------------------------------------------- /src/css/oswald.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Oswald'; 3 | font-weight: 300; 4 | font-style: normal; 5 | src: url('../fonts/Oswald-300/Oswald-300.eot'); 6 | src: url('../fonts/Oswald-300/Oswald-300.eot?#iefix') format('embedded-opentype'), 7 | local('Oswald Light'), 8 | local('Oswald-300'), 9 | url('../fonts/Oswald-300/Oswald-300.woff2') format('woff2'), 10 | url('../fonts/Oswald-300/Oswald-300.woff') format('woff'), 11 | url('../fonts/Oswald-300/Oswald-300.ttf') format('truetype'), 12 | url('../fonts/Oswald-300/Oswald-300.svg#Oswald') format('svg'); 13 | } 14 | 15 | @font-face { 16 | font-family: 'Oswald'; 17 | font-weight: 400; 18 | font-style: normal; 19 | src: url('../fonts/Oswald-regular/Oswald-regular.eot'); 20 | src: url('../fonts/Oswald-regular/Oswald-regular.eot?#iefix') format('embedded-opentype'), 21 | local('Oswald Regular'), 22 | local('Oswald-regular'), 23 | url('../fonts/Oswald-regular/Oswald-regular.woff2') format('woff2'), 24 | url('../fonts/Oswald-regular/Oswald-regular.woff') format('woff'), 25 | url('../fonts/Oswald-regular/Oswald-regular.ttf') format('truetype'), 26 | url('../fonts/Oswald-regular/Oswald-regular.svg#Oswald') format('svg'); 27 | } 28 | -------------------------------------------------------------------------------- /contributors.md: -------------------------------------------------------------------------------- 1 | #Contributors 2 | 3 | List of entities that had contributor in some way to the Uumm project. 4 | 5 | ###Dani Armengol 6 | 7 | - Initial concept brainstorming with Taster project, constat feedback given. 8 | 9 | ###Gregg Albritton 10 | 11 | - [Naming brainstorming](https://twitter.com/xavivives/status/885213103583047680) 12 | - [Similar projects references](https://twitter.com/xavivives/status/885213103583047680) 13 | - [Broken Meritorcray feedback](https://mail.google.com/mail/u/0/#inbox/15e3ca4f88c156e8) 14 | - [Corrections on Broken Meritocracy](https://github.com/xavivives/Uumm/pull/2) 15 | 16 | ###Biggamax 17 | 18 | - [Suggestions on contract migration](https://www.reddit.com/r/ethdev/comments/6oofer/im_building_a_contributionbased_governance_daap/dkkowjh/?st=j5giill2&sh=27d01a1a) 19 | 20 | ###Dani Magan 21 | 22 | - [Heads up with the public deploy being down](https://twitter.com/xavivives/status/893247116444930048) 23 | 24 | ###Lydia Law 25 | - Logo concept brainstorming 26 | 27 | ###Brian Fitzgerald 28 | 29 | -[Suggestions on revenue sharing](https://twitter.com/xavivives/status/900622199341690880) 30 | 31 | -[Reported wrong functioning of UI](https://github.com/xavivives/Uumm/issues/1) 32 | 33 | ###Xavier Vives 34 | 35 | -Suggestions on how to frame the Broken meritocracy article 36 | 37 | ###Griff 38 | - Overall discussion about meritocracy and liquid democracy 39 | 40 | ###Luke 41 | - Overall discussion about governance 42 | - Great feedback on reputation sytstems 43 | -------------------------------------------------------------------------------- /src/UnconfirmedProposalCard.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const cardStyle = 4 | { 5 | display: 'flex', 6 | flexDirection: 'column', 7 | flexWrap: 'nowrap', 8 | justifyContent: 'flex-start', 9 | alignItems: 'flex-start', 10 | padding : 5, 11 | margin:5 12 | } 13 | 14 | const containerStyle = 15 | { 16 | display: 'flex', 17 | flexDirection: 'row', 18 | flexWrap: 'nowrap', 19 | justifyContent: 'space-between', 20 | alignItems: 'center', 21 | width:"100%" 22 | } 23 | 24 | const pStyle = 25 | { 26 | color:"#aaa" 27 | } 28 | 29 | const cellStyle = 30 | { 31 | flexGrow:1, 32 | textAlign:"center", 33 | flexShring:0 34 | } 35 | 36 | class ProposalCard extends React.Component { 37 | 38 | constructor(props) 39 | { 40 | super() 41 | } 42 | 43 | render() 44 | { 45 | return ( 46 |
47 |

{this.props.proposalData.title}

48 | 49 |
50 | 51 |
52 |
53 |
54 |
55 |

...unconfirmed

56 |
57 |
58 | ) 59 | } 60 | } 61 | 62 | export default ProposalCard -------------------------------------------------------------------------------- /support/ContractStructure: -------------------------------------------------------------------------------- 1 | 7Vlbc+IgFP41zrQPndHcTB9rrG4furNT9/KMCSZsMWQJ3vbX7yEhN4Na27SznTEvho8DHPg+DofYM73ldspREj2yANOe0Q+2PXPcM4zBoO/Aj0R2OeKYtzkQchIoowqYkb9YgX2FrkiA04ahYIwKkjRBn8Ux9kUDQ5yzTdNswWhz1ASFuAXMfETb6C8SiChHXWNY4V8wCaNi5IGj5jdH/nPI2SpW4/UMc5E9efUSFX2piaYRCtimBpn3PdPjjIn8bbn1MJVrWyxb3m5yoLb0m+NYvKSBkTdYI7pSU3+IBWfKObErFgT8TORrzAT8jDYREXiWIF9iG9AAYJFYUigN4DWFLp6xxyjjWXPTNeam40DNglBawwMbu4ElcRaLCVoSKgXjsRUnmIMHX/FGVSqNDAxVrnVymz2AI0rCGDAfJg/NzVF7NdQCrTEXeFuD1OpMMVtiwXdgomqHiiglZEsVN5UqBo7CopoiimZICTEsO67IgBfFh54bs8XNN84SliIwcigMNJrDGjmhyGaaIwFZl5A9InGEOREp9DJlMOcYxcCYPS6swYN6A00fBwfab9qtXiaTsd3vt/UygcfzPpFeyvJHCMZqCeZR0n9SG7nVYVl0y63ju3i+0MQChN2F/4m4tVwNt7aGW7cDbu0WtxM4ZEgc6tl9qNhdXth9Dbv2R7Lr6EL9dtc1OXPXtmxNWF24PvY/EzllCP2IsFp6W7FT7KU0QXGDIefPSqZu2drcpNli3YHBwEi2VWWx955wQiV3WR4rOIJEFtI1e8RiKqdenPa1o7th6WdjQ9KaObu3xXPPTp3ib/N/iqUbnvLoCnL26zM82JM2CEE05csxOIDmmYEUbcJILDIe7ZGcLChtJViqFFkTHsUL2ZVUF4HluVOwYEk+ZR/C5ndZGN9YB3R9dBPoRN+Bxg37tMitoUbkZhcibycPHsdISM0lnP2Wt6z2SZMrYJVmC6TM0hceNBfC9wnXXS6s9+K7nVDMMjJVylhu6zfdClpNS03tX2VqNj+Z1qIa7QmnjK51NvrxL0I8JUTLPn1r0eU+nRyv7eTnRxJkKjl+bJ1zzT3zMLpcX1Wk0SXB75ZnDQ/mWbXtezxKNbd6K9pc+SsuV6dodhcEsNdBOOBcP8abPfz6SPC7BKz/KGDpdGrpjk67A52a7Y+mkAcd+tQCUmpUXbg9k1vLNVvcvlcWbLa/uZ6i9hi3XWZOr/4Ue1FUmVgf+bTjdhMsoFj9eZPV1f4hM+//AQ== -------------------------------------------------------------------------------- /src/CreateProjectPage.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import TextField from 'material-ui/TextField' 3 | import Dialog from 'material-ui/Dialog' 4 | import FlatButton from 'material-ui/FlatButton' 5 | 6 | class CreateProjectPage extends React.Component 7 | { 8 | constructor(props) 9 | { 10 | super(); 11 | this.state = {"projectName" : ""} 12 | } 13 | 14 | onCreate=()=> 15 | { 16 | this.props.onCreate(this.state.projectName) 17 | } 18 | 19 | onCancel=()=> 20 | { 21 | this.props.onCancel() 22 | } 23 | 24 | onTextChange = (e, newText) => { 25 | if(newText.length<32) 26 | this.setState({projectName:newText}) 27 | } 28 | 29 | render() 30 | { 31 | const actions = [ 32 | , 37 | 43 | ] 44 | 45 | return ( 46 | 52 | 53 | 59 | 60 | 61 | ) 62 | } 63 | } 64 | 65 | export default CreateProjectPage; -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 17 | 18 | 27 | Uumm 28 | 29 | 30 |
31 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/ProjectsListPage.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import Uumm from './UummContractInterface.js' 3 | import ProjectsList from './ProjectsList.js' 4 | import CreateProjectPage from './CreateProjectPage.js' 5 | import RaisedButton from 'material-ui/RaisedButton' 6 | 7 | class ProjectsListPage extends Component 8 | { 9 | constructor(props) { 10 | super(props) 11 | window.location.hash = "projects" 12 | this.state = {"createDialogIsOpen" : false}; 13 | } 14 | 15 | closeDialog=()=> 16 | { 17 | this.setState({'createDialogIsOpen':false}) 18 | } 19 | 20 | onCreateProjectTap=(projectName)=> 21 | { 22 | this.setState({'createDialogIsOpen':true}) 23 | } 24 | 25 | createProject=(projectName)=> 26 | { 27 | this.setState({'createDialogIsOpen':false}) 28 | 29 | Uumm.createProject(projectName) 30 | .then(()=>{}) 31 | .catch((error)=>{console.error(error)}) 32 | } 33 | 34 | onProjectSelected=(projectData)=> 35 | { 36 | this.props.onProjectSelected(projectData) 37 | } 38 | 39 | render() { 40 | 41 | return ( 42 |
43 | 49 | 50 | 54 | 55 | 60 |
61 | ) 62 | } 63 | } 64 | 65 | export default ProjectsListPage 66 | -------------------------------------------------------------------------------- /DeconstructionGovernanceExamples.js: -------------------------------------------------------------------------------- 1 | { 2 | name:'Small busineses', 3 | decisions:['what pricing put', 'employees salaries'] 4 | participants:'Owner', 5 | merit:'Put energy on understanding and fixing a problem', 6 | metric:'Document telling the business is her', 7 | incentives: 8 | } 9 | 10 | 11 | { 12 | name:'Basketball team', 13 | decisions:['What player plays', 'what moves'] 14 | participants:'Trainer', 'Point Guard', 15 | merit:'Capacity to read the game', 'know the players', 16 | metric:'Position','trust', 17 | incentives:'Win the game', 'reputation', 'economic' 18 | } 19 | 20 | { 21 | name:'Corporation', 22 | decisions:['Overall direction'] 23 | participants:'Shareholders', 'board of directors', 24 | merit:'Own company shares', 25 | metric:'Contracts', 26 | incentives:'Increase company valuation' 27 | } 28 | 29 | { 30 | name:'Engineering department', 31 | decisions:['How to implement somethiong', 'employees salaries'] 32 | participants:'Head of engineering, employees' 33 | merit:['pervious experience', 'fidelity to the company', 'academic titles'] 34 | metric:'Contract', 35 | incentives:['reputation', 'payout', 'economic'] 36 | } 37 | 38 | { 39 | name:'Futarchy', 40 | decisions:['any'] 41 | merit:'Forecast futur events', 42 | } 43 | 44 | { 45 | name:'Dictatorship', 46 | decisions:['any'] 47 | merit:'Control military', 48 | incentives:['Keep control','economic'] 49 | } 50 | 51 | { 52 | name:'Futarchy', 53 | decisions:['any'] 54 | merit:'Forecast futur events correctly', 55 | metric:'Number of certain predictions' 56 | } 57 | 58 | { 59 | name:'Bitcoin', 60 | decisions:['change the protocol', 'validate transaction'] 61 | merit:['validate transactions','secure the network'] 62 | metric:'hashing power', 63 | incentives:'award bitcoins to themselves', 'economic' 64 | } 65 | 66 | participants:'Who can make decisions?' 67 | vote:'How is the decision defined?' 68 | merit:'What gives an entity the right to vote?' 69 | metric:'How to quantify the merit' 70 | incentives:'Why will the entity make good decisions?' -------------------------------------------------------------------------------- /config/paths.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var fs = require('fs'); 3 | 4 | // Make sure any symlinks in the project folder are resolved: 5 | // https://github.com/facebookincubator/create-react-app/issues/637 6 | var appDirectory = fs.realpathSync(process.cwd()); 7 | function resolveApp(relativePath) { 8 | return path.resolve(appDirectory, relativePath); 9 | } 10 | 11 | // We support resolving modules according to `NODE_PATH`. 12 | // This lets you use absolute paths in imports inside large monorepos: 13 | // https://github.com/facebookincubator/create-react-app/issues/253. 14 | 15 | // It works similar to `NODE_PATH` in Node itself: 16 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders 17 | 18 | // We will export `nodePaths` as an array of absolute paths. 19 | // It will then be used by Webpack configs. 20 | // Jest doesn’t need this because it already handles `NODE_PATH` out of the box. 21 | 22 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. 23 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. 24 | // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421 25 | 26 | var nodePaths = (process.env.NODE_PATH || '') 27 | .split(process.platform === 'win32' ? ';' : ':') 28 | .filter(Boolean) 29 | .filter(folder => !path.isAbsolute(folder)) 30 | .map(resolveApp); 31 | 32 | // config after eject: we're in ./config/ 33 | module.exports = { 34 | // Changed from build to build_webpack so smart contract compilations are not overwritten. 35 | // Xavi edit: changed from build_webpack to docs, so I don't need to copy it over everytime when deploying 36 | appBuild: resolveApp('docs'), 37 | appPublic: resolveApp('public'), 38 | appHtml: resolveApp('public/index.html'), 39 | appIndexJs: resolveApp('src/index.js'), 40 | appPackageJson: resolveApp('package.json'), 41 | appSrc: resolveApp('src'), 42 | yarnLockFile: resolveApp('yarn.lock'), 43 | testsSetup: resolveApp('src/setupTests.js'), 44 | appNodeModules: resolveApp('node_modules'), 45 | ownNodeModules: resolveApp('node_modules'), 46 | nodePaths: nodePaths 47 | }; 48 | -------------------------------------------------------------------------------- /support/DeconstructionGovernanceExamples.js: -------------------------------------------------------------------------------- 1 | { 2 | name:'Small busineses', 3 | decisions:['what pricing put', 'employees salaries'] 4 | participants:'Owner', 5 | merit:'Put energy on understanding and fixing a problem', 6 | metric:'Document telling the business is her', 7 | incentives: 8 | } 9 | 10 | 11 | { 12 | name:'Basketball team', 13 | decisions:['What player plays', 'what moves'] 14 | participants:'Trainer', 'Point Guard', 15 | merit:'Capacity to read the game', 'know the players', 16 | metric:'Position','trust', 17 | incentives:'Win the game', 'reputation', 'economic' 18 | } 19 | 20 | 21 | 22 | { 23 | name:'Corporation', 24 | decisions:['Overall direction'] 25 | participants:'Shareholders', 'board of directors', 26 | merit:'Own company shares', 27 | metric:'Contracts', 28 | incentives:'Increase company valuation' 29 | } 30 | 31 | { 32 | name:'Engineering department', 33 | decisions:['How to implement somethiong', 'employees salaries'] 34 | participants:'Head of engineering, employees' 35 | merit:['pervious experience', 'fidelity to the company', 'academic titles'] 36 | metric:'Contract', 37 | incentives:['reputation', 'payout', 'economic'] 38 | } 39 | 40 | { 41 | name:'Futarchy', 42 | decisions:['any'] 43 | merit:'Forecast futur events', 44 | } 45 | 46 | { 47 | name:'Dictatorship', 48 | decisions:['any'] 49 | merit:'Control military', 50 | incentives:['Keep control','economic'] 51 | } 52 | 53 | { 54 | name:'Futarchy', 55 | decisions:['any'] 56 | merit:'Forecast futur events correctly', 57 | metric:'Number of certain predictions' 58 | } 59 | 60 | { 61 | name:'Bitcoin', 62 | decisions:['change the protocol', 'validate transaction'] 63 | merit:['validate transactions','secure the network'] 64 | metric:'hashing power', 65 | incentives:'award bitcoins to themselves', 'economic' 66 | } 67 | 68 | participants:'Who can make decisions?' 69 | vote:'How is the decision defined?' 70 | merit:'What gives an entity the right to vote?' 71 | metric:'How to quantify the merit' 72 | incentives:'Why will the entity make good decisions?' -------------------------------------------------------------------------------- /src/Page.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import Warning from './Warning.js' 3 | import RaisedButton from 'material-ui/RaisedButton' 4 | 5 | const FloatingButtonStyle={ 6 | margin: 0, 7 | top: 'auto', 8 | right: 20, 9 | bottom: 20, 10 | left: 'auto', 11 | position: 'fixed', 12 | zIndex:100 13 | }; 14 | 15 | const FloatingButtonStyle2={ 16 | margin: 0, 17 | top: 'auto', 18 | right: 20, 19 | bottom: 60, 20 | left: 'auto', 21 | position: 'fixed', 22 | zIndex:100 23 | }; 24 | 25 | const twitterLink='http://twitter.com/home?status=@xavivives About this Uumm tool...' 26 | const issueLink='https://github.com/xavivives/uumm/issues/new' 27 | 28 | class Page extends Component 29 | { 30 | render(){ 31 | 32 | return ( 33 |
34 |
35 |
36 | 37 | 38 |

This tool is highly experiemental and on an alpha stage still. Don't use it for important stuff

39 |
40 | 41 | {this.props.children} 42 | 43 | 50 | 51 | 59 | 60 |
61 |
62 |
63 | ) 64 | } 65 | } 66 | 67 | export default Page 68 | -------------------------------------------------------------------------------- /support/Merit Examples.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | These examples are to show how current governance system fits on the described meritocracy 3 | _The numbers (1,2,3) make reference to the described merit properties_ 4 | 5 | 6 | ## Nation state elections 7 | **Decisions to make:** Choose the representatives 8 | 9 | **Participants:** Legal citizens 10 | 11 | **Merit properties:** 12 | 13 | 1. The required merit is to be a citizen. 14 | 2. Merit is bound to your identity, therefore can't be exchanged 15 | 3. Merit is tokenized by using ID cards. Each ID card is one vote. 16 | 17 | **Reality (undesired consequences):** 18 | 19 | 1. All the participants (whatever they have the right capacities to make good decisions or not) have the same decision power. There is no required skill to vote. 20 | 2. While the ID card can't be exchanged, the opinion of the participants can be easily manipulated by media (especially because they don't have the capacities to understand the problems (#1)) which is manipulated by lobbyist, which are the entities with more economic power. 21 | 3. Id cards tokenize merit but not without compromising the other properties. 22 | 23 | ## Bitcoin 24 | **Decisions to make:** Change the protocol rules 25 | 26 | **Participants:** Miners 27 | 28 | **Merit properties:** 29 | 30 | 1. The required merit is a proof that it recently secured the network by validating transactions. 31 | 2. POW can't be exchanged. It is also directly attached to the coinbase reward, disincentivizing any attempt. 32 | 3. How many times a miner has been the first to find the block hash within a defined amount of blocks. 33 | 34 | **Reality (undesired consequences):** 35 | 36 | 1. Miners don't want network upgrades that don't maximize their profit. A brutal amount of electricity is used. 37 | 2. All good here. 38 | 3. All good here. 39 | 40 | ## A company department 41 | **Decisions to make:** What features of a product should we focus, who to hire, how much to pay? 42 | 43 | **Participants:** Head of the department 44 | 45 | **Merit properties:** 46 | 47 | 1. Someone with expertise on the subject, with fidelity to the company. 48 | 2. The merit is being himself, can't be exchanged, can be influenced. 49 | 3. Role defined in its contract ( a consequence of the time working for the company, resume...) 50 | 51 | **Reality (undesired consequences):** 52 | 53 | All good here, probably because it is not in a trustless environment, and it is easy to adapt. -------------------------------------------------------------------------------- /src/CreateProposalPage.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import TextField from 'material-ui/TextField' 3 | import Dialog from 'material-ui/Dialog' 4 | import FlatButton from 'material-ui/FlatButton' 5 | 6 | class CreateProposalPage extends React.Component 7 | { 8 | constructor(props) 9 | { 10 | super(); 11 | this.state = { 12 | "proposalTitle" : "", 13 | "proposalReference" : "", 14 | "tokenAmount" : "" 15 | } 16 | } 17 | 18 | onCreate=()=> 19 | { 20 | this.props.onCreate(this.state.proposalTitle, this.state.proposalReference, this.state.tokenAmount) 21 | } 22 | 23 | onCancel=()=> 24 | { 25 | this.props.onCancel() 26 | } 27 | 28 | onProposalTitleTextChange = (e, newText) => { 29 | if(newText.length<32) 30 | this.setState({proposalTitle:newText}) 31 | } 32 | 33 | onProposalReferenceTextChange = (e, newText) => { 34 | this.setState({proposalReference:newText}) 35 | } 36 | 37 | onTokenAmountTextChange = (e, newText) => { 38 | if(isNaN(newText)) 39 | return 40 | this.setState({tokenAmount:newText}) 41 | } 42 | 43 | render() 44 | { 45 | const actions = [ 46 | , 51 | 57 | ] 58 | 59 | return ( 60 | 66 | 67 | 73 | 74 |
75 | 76 | 82 | 83 |
84 | ) 85 | } 86 | } 87 | 88 | export default CreateProposalPage; -------------------------------------------------------------------------------- /support/Interoperable Adhocracy.md: -------------------------------------------------------------------------------- 1 | # Interoperable Adhocracy 2 | In the previous document we suggested an improvment on how a single decision making process could be improved. 3 | 4 | On this one we'll try to envision how a decentralized ecosystem may function as a whole. 5 | 6 | ### Why adhocracy? 7 | _Governance_ is a broad concept very loosely used. The new decentralized paradigmn has a set of properties that are much better captured by adhocracy. 8 | 9 | >[Adhocracy](https://en.wikipedia.org/wiki/Adhocracy#Types_of_adhocracy) is characterized by an adaptive, creative and flexible integrative behavior based on **non-permanence** and **spontaneity**. - Wikipedia 10 | 11 | 12 | ## Voluntary 13 | 14 | If you go over adhocracy [characteristics](https://en.wikipedia.org/wiki/Adhocracy#Characteristics_of_adhocracy) you will realize that many of those are just the result of participation being voluntary, therefore the _non-permanence_ feature. 15 | 16 | While this may not be the case of some organizations. I belive we could assume it will be the case for most of them 17 | 18 | ### Darwinian selection 19 | Voluntary participation on a governance system serves as [natural selection](https://en.wikipedia.org/wiki/Universal_Darwinism) tool. 20 | 21 | This is important because it becomes another governance process at the most fundamental level. It tells if a project should exist or not. 22 | 23 | ## Identity agnostic 24 | 25 | If the goal is to make the best decision possible, it should not matter where the ideas com from. Anyone/anything should be a potential participant, whatever it's a kid, an AI, a prediction market or another governance entity. 26 | 27 | Is the merit's job to filter who can participate. 28 | 29 | ## Non-permanence 30 | The none-permanence feature makes organizations to be resilient when an associated entity drops the relationship. 31 | 32 | ## Nestable governance 33 | That means that a governance system should be able to act as a participant entity to another governance system. 34 | 35 | ### Keep it simple 36 | Governance models tend to complexity. By nesting a governance inside another the goals of a single governance entity can be keep simpler and therefore making the required merits simpler as well. 37 | 38 | This means that a governance entity would be used as merit agregator of its participants. 39 | 40 | ### But complex 41 | This would allow the creation of hierachical structures, making the system as a whole complex, while keeping each entity simple. 42 | 43 | This is common in most goverances already (departments of a company, states/counties), that's why I was surprized to not find any existing proposal within the decentralized paradigm. 44 | 45 | 46 | ### Interoperability 47 | 48 | 49 | ### Wisdown of the crowds 50 | We never witness the outcomes of [The DAO] (https://en.wikipedia.org/wiki/The_DAO_(organization)) governance. Probably [it was not aimed to succeed](https://forum.daohub.org/t/the-dao-are-we-taking-the-wisdom-of-the-crowd-too-far/1486/8) anyway to put the [wisdom of the crowds](https://en.wikipedia.org/wiki/Wisdom_of_the_crowd) in practice. 51 | 52 | (https://forum.daohub.org/t/the-dao-are-we-taking-the-wisdom-of-the-crowd-too-far/1486/8) 53 | 54 | ###Friction less 55 | ###Voluntary 56 | ###Simple 57 | ###Enforcable or turstable 58 | -------------------------------------------------------------------------------- /src/ProjectOverview.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import State from './State.js' 3 | import Web3AutoSetup from './Web3AutoSetup.js' 4 | import OwnershipChart from './OwnershipChart.js' 5 | import Numeral from 'numeral' 6 | 7 | const overflowStyle = { 8 | whiteSpace: "nowrap", 9 | textOverflow: "ellipsis", 10 | overflow: "hidden" 11 | } 12 | 13 | const subheaderStyle = { 14 | color:"grey", 15 | marginBottom:-10, 16 | marginTop:0 17 | } 18 | 19 | class ProjectDetails extends React.Component { 20 | 21 | constructor(props) 22 | { 23 | super() 24 | } 25 | 26 | getAddressStyle=(color)=> 27 | { 28 | var style = overflowStyle 29 | style.color = color 30 | return style 31 | } 32 | 33 | render() 34 | { 35 | var projectData = State.getEmptyProject() 36 | var contributorData = State.getEmptyContributor() 37 | if(State.data.projects[this.props.projectId]) 38 | projectData = State.data.projects[this.props.projectId] 39 | 40 | if(projectData.contributors) 41 | if(projectData.contributors[Web3AutoSetup.currentAccount]) 42 | contributorData = projectData.contributors[Web3AutoSetup.currentAccount] 43 | 44 | //var ownership = Numeral(contributorData.valueTokens/projectData.totalSupply).format('0.0%') 45 | 46 | return ( 47 |
48 | 49 |
50 | 51 |
52 | 58 |
59 | 60 |
61 | 62 |
Your address
63 |

{this.props.userAddress}

64 |
Your tokens
65 |

{contributorData.valueTokens}

66 |
Available ethereum to withdraw
67 |

{contributorData.etherBalance} ETH

68 | 69 | 70 |
Project ID
71 |

{projectData.id}

72 |
Project total token supply
73 |

{projectData.totalSupply}

74 | 75 |
Required concensus
76 |

{Numeral(projectData.requiredConcensus).format('0%')}

77 | 78 |
Required participation
79 |

{Numeral(projectData.requiredParticipation).format('0%')}

80 |
81 | 82 |
83 |
84 | ) 85 | } 86 | } 87 | 88 | export default ProjectDetails -------------------------------------------------------------------------------- /support/Reputation for governance.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Reputation for governance 4 | 5 | Since we can't directly tokenize them, we can use the past as an indicator of the future. We can quantify proven capacities, and use it as merit. 6 | 7 | Within this context, merit defines a required capacity of an entity to make decisions, while reputation is a proven record of a capacity. 8 | 9 | This makes reputation systems extremely suitable for governance. 10 | 11 | 12 | ### Concensus problem 13 | 14 | In both cases we still need to have concensus over these metrics, at least among the participants. 15 | 16 | 17 | 18 | ### Centralized 19 | There are thousands of reputation systems already in use (5 stars rating, credentials, comments, followers, likes...), the problem is that they usually live in mutable (therefore can be altered) permission-ed (therefore un-accessible) databases. And because they're owned by entities that monetize on them, they have no incentive to change. 20 | 21 | ### Decentralized 22 | The new paradigm is different, and there are already [so many reasons](https://medium.com/@2W/fixing-orwellian-reputation-systems-4d01d489dcb7) to move away from the centralized reputation. 23 | 24 | Communities/platforms/DAOs that live on decentralized networks do not benefit by keeping all this data, it's quite the opposite. They enhance each other when the data is accessible. 25 | 26 | 27 | ## Towards merit as reputation 28 | So, how do we get there? 29 | 30 | ### Decentralized identity 31 | In order to create decentralized reputation we need decentralized identities. Luckily, with different aproaches, there are several endeveours on the works: [DID](https://w3c-ccg.github.io/did-spec/), [UPort](https://www.uport.me/), [Blockstack](https://blockstack.org/), [Keybase](https://keybase.io), [identifi](https://github.com/identifi/) (missing any?) 32 | 33 | ### Accessible reputation 34 | While each governance is free to use any reputation metric it wants, a standaritzation would make things much accessible. In the same fashion that the [ERC20](http://www.investopedia.com/news/what-erc20-and-what-does-it-mean-ethereum/) has enabled all sorts of new services and platforms. Having and standard for decentralized reputation will greatly benefit the community. 35 | 36 | While there have been attempts to standardize reputation [in the past](https://tools.ietf.org/html/rfc7071), this document is only attempt of decentralized reputation I'm aware of: 37 | 38 | [Decentralized Cooperation needs Decentralized Reputation](https://github.com/WebOfTrustInfo/rebooting-the-web-of-trust/blob/master/topics-and-advance-readings/DecentralizedCooperationNeedsDecentralizedReputation.md) by [Noah Thorp](https://twitter.com/noahthorp) (2015) 39 | 40 | ### Subjective reputation 41 | The previous assumes reputation systems to be objective. Meaning that at least the participants need to have consensus over the state of a reputation metric. 42 | To my knowledge blockchains are the more suitable technology for it. 43 | 44 | In general when we talk about reputation, we refer to subjective reputation. How do an entity _feels_ about something. Each entity may have a different opinon. 45 | 46 | Subjective reputation may be very useful for decision making processes, but makes things harder to implement. I currently don't have an opinion on how this could be done. 47 | 48 | like [identifi](https://github.com/identifi/) and [Trust Graph](https://github.com/trustgraph/trustgraph) work on P2P basis. -------------------------------------------------------------------------------- /src/LandingPage.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactMarkdown from'react-markdown' 3 | import RaisedButton from 'material-ui/RaisedButton' 4 | 5 | const whatIsThis=` 6 | # What is this 7 | 8 | In recent years a new paradigm around decentralization has emerged. 9 | Technologies such as [Ethereum](https://www.ethereum.org/), [IPFS](https://ipfs.io/) or [Bitcoin](https://en.wikipedia.org/wiki/Bitcoin) offer a new set of possibilities for re-designing most of the systems that drive our society. 10 | 11 | Uumm is an open-source, experimental tool, for the process of decision making build on top of these new exciting technologies. 12 | 13 | # Where are we 14 | We have a first working prototype. On the [Github repo](https://github.com/xavivives/uumm) you can find all the details about it. 15 | 16 | We're already [designing the next iteration](https://github.com/xavivives/Uumm/blob/master/support/Broken%20meritocracy.md), while keep polishing this one. 17 | 18 | [Follow us on twitter](https://twitter.com/xavivives), to stay up to date.` 19 | 20 | const imgUrl= process.env.PUBLIC_URL + '/img/horseAnatomy.jpg' 21 | 22 | const backgroundImageStyle={ 23 | backgroundColor:'grey', 24 | height:window.innerHeight, 25 | minWidth: '100%', 26 | backgroundImage:'url('+imgUrl+')', 27 | backgroundRepeat:'no-repeat', 28 | backgroundSize:'cover', 29 | backgroundPosition:'center', 30 | } 31 | 32 | const titleStyle ={ 33 | color: '#666666', 34 | fontSize: '3em', 35 | margin:0, 36 | } 37 | 38 | const subtitleStyle = { 39 | color: '#666666' 40 | } 41 | 42 | class LandingPage extends React.Component { 43 | 44 | constructor(props) 45 | { 46 | super() 47 | window.location.hash = "intro" 48 | } 49 | 50 | render() 51 | { 52 | return ( 53 |
54 |
55 |
56 |

57 | uumm 58 |

59 |

60 | decentralized meritocracy 61 |

62 |
63 | 68 | 69 |
70 |
71 |
72 |
73 | 74 |
75 | 76 |
77 | 82 |
83 |
84 |
85 |
86 |
87 | ) 88 | } 89 | } 90 | 91 | export default LandingPage -------------------------------------------------------------------------------- /src/ProjectsList.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ProjectCard from './ProjectCard'; 3 | import UnconfirmedProjectCard from './UnconfirmedProjectCard'; 4 | import Uumm from './UummContractInterface.js' 5 | import State from './State.js' 6 | import Divider from 'material-ui/Divider'; 7 | 8 | class ProjectsList extends React.Component 9 | { 10 | componentWillMount=()=> 11 | { 12 | this.state={"contentLoaded":false} 13 | Uumm.isReady() 14 | .then(()=>{ 15 | Uumm.getUserProjects() 16 | .then(()=>{ 17 | this.setState({"contentLoaded":true}) 18 | }).catch(function(error){console.error(error)}) 19 | }).catch(function(error){console.error(error)}) 20 | } 21 | 22 | componentWillReceiveProps=(nextProps)=> 23 | { 24 | if(nextProps.userAddress===this.props.userAddress) 25 | return 26 | 27 | Uumm.isReady() 28 | .then(()=>{ 29 | Uumm.getUserProjects().catch(function(error){console.error(error)}) 30 | }).catch(function(error){console.error(error)}) 31 | } 32 | 33 | onProjectSelected = (projectData)=> 34 | { 35 | this.props.onProjectSelected(projectData) 36 | } 37 | 38 | render() 39 | { 40 | 41 | var projects = []; 42 | var user= State.getEmptyUser() 43 | 44 | if(State.data.users[this.props.userAddress]) 45 | user = State.data.users[this.props.userAddress] 46 | 47 | for(var i = 0; i < user.projectsRef.length; i++) 48 | { 49 | var projectId = State.data.users[this.props.userAddress].projectsRef[i] 50 | 51 | if(!State.data.projects[projectId]) 52 | continue 53 | 54 | var projectData = State.data.projects[projectId] 55 | 56 | projects.push( 57 | ) 63 | 64 | 65 | projects.push() 66 | 67 | } 68 | 69 | //Unconfirmed projects 70 | for (var unconfirmedProjectId in State.data.unconfirmedProjects) 71 | { 72 | if (!State.data.unconfirmedProjects.hasOwnProperty(unconfirmedProjectId)) 73 | continue 74 | 75 | var unconfirmedProjectData = State.data.unconfirmedProjects[unconfirmedProjectId] 76 | 77 | projects.push( 78 | ) 84 | 85 | projects.push() 86 | } 87 | 88 | var hint="" 89 | if(this.state.contentLoaded) 90 | hint="Your projects" 91 | if(projects.length===0 && this.state.contentLoaded ) 92 | hint="This account has no associated projects. Why don't you create a new one?" 93 | 94 | return ( 95 |
96 |

97 | 98 |
99 |

{hint}

100 | 101 | {projects} 102 | 103 |
104 |
105 | ) 106 | } 107 | } 108 | 109 | export default ProjectsList; -------------------------------------------------------------------------------- /src/ProposalChart.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Sunburst} from 'react-vis' 3 | import Numeral from 'numeral' 4 | import Chroma from 'chroma-js' 5 | 6 | const startColor= "#ff3366" 7 | const endColor= "#ffdc00" 8 | 9 | class ProposalChart extends React.Component { 10 | 11 | constructor(props) 12 | { 13 | super() 14 | this.state = { 15 | color:startColor, 16 | stake:0, 17 | id:undefined, 18 | user:{} 19 | } 20 | this.resetTimeout = {} 21 | window.setTimeout(this.showGraph,3000) 22 | } 23 | 24 | getData=(size= 0 ,color = "#e0d9cc" ,title="", children=[])=> 25 | { 26 | return { 27 | title:title, 28 | color:color, 29 | size:size, 30 | children:children, 31 | } 32 | } 33 | 34 | getCenterContentStyle=()=> 35 | { 36 | return { 37 | "position":"absolute", 38 | "top":0, 39 | "left":0, 40 | "width":this.props.size, 41 | "height":this.props.size, 42 | "display":"flex", 43 | "flexDirection":"column", 44 | "justifyContent":"center", 45 | "alignItems":"center", 46 | "zIndex":-1 47 | } 48 | } 49 | 50 | buildEmptyData=()=> 51 | { 52 | let data = { 53 | children:[this.getData(1),this.getData(0)] 54 | } 55 | return data 56 | } 57 | 58 | buildData=(positive, negative, total, user)=> 59 | { 60 | let rest = total-positive-negative 61 | let positiveData = this.getData(positive, startColor, "Positive"); 62 | let negativeData = this.getData(negative, startColor, "Negative"); 63 | let restData = this.getData(rest); 64 | if(user>0) 65 | positiveData.children.push(this.getData(user, startColor, "You")) 66 | else if(user<0) 67 | negativeData.children.push(this.getData(-user, startColor, "You")) 68 | 69 | let data = { 70 | children:[positiveData, negativeData, restData] 71 | } 72 | 73 | return data 74 | } 75 | 76 | onMouseOver=(data)=> 77 | { 78 | this.setState({ 79 | color:data.color, 80 | stake:data.size, 81 | title:data.title 82 | }) 83 | 84 | clearTimeout(this.resetTimeout); 85 | this.resetTimeout = window.setTimeout(()=>{ 86 | this.onMouseOut() 87 | },2000) 88 | } 89 | 90 | //Not triggering for unkown reason 91 | onMouseOut=(data)=> 92 | { 93 | 94 | } 95 | 96 | showGraph=()=> 97 | { 98 | this.setState({showGraph:true}) 99 | } 100 | 101 | render() 102 | { 103 | let data = this.buildEmptyData() 104 | 105 | let percentage = Numeral(this.state.stake/this.props.total).format('0.0%') 106 | let shares = this.state.stake+"/"+this.props.total 107 | 108 | if(this.state.showGraph) 109 | data = this.buildData(this.props.positive, this.props.negative, this.props.total, this.props.user) 110 | 111 | return ( 112 |
113 | 114 |
115 |

{percentage}

116 |

{shares}

117 |
118 | 119 | 129 |
130 | ) 131 | } 132 | } 133 | 134 | export default ProposalChart -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "truffle-box-status", 3 | "version": "0.1.1", 4 | "private": true, 5 | "devDependencies": { 6 | "autoprefixer": "6.5.1", 7 | "babel-core": "6.17.0", 8 | "babel-eslint": "7.1.1", 9 | "babel-jest": "17.0.2", 10 | "babel-loader": "6.2.7", 11 | "babel-preset-react-app": "^2.0.1", 12 | "case-sensitive-paths-webpack-plugin": "1.1.4", 13 | "chalk": "1.1.3", 14 | "connect-history-api-fallback": "1.3.0", 15 | "cross-spawn": "4.0.2", 16 | "css-loader": "0.26.0", 17 | "detect-port": "1.0.1", 18 | "eslint": "3.8.1", 19 | "eslint-config-react-app": "^0.5.0", 20 | "eslint-loader": "1.6.0", 21 | "eslint-plugin-flowtype": "2.21.0", 22 | "eslint-plugin-import": "2.0.1", 23 | "eslint-plugin-jsx-a11y": "2.2.3", 24 | "eslint-plugin-react": "6.4.1", 25 | "extract-text-webpack-plugin": "1.0.1", 26 | "file-loader": "0.9.0", 27 | "filesize": "3.3.0", 28 | "fs-extra": "0.30.0", 29 | "gh-pages": "^1.0.0", 30 | "gzip-size": "3.0.0", 31 | "html-webpack-plugin": "2.24.0", 32 | "http-proxy-middleware": "0.17.2", 33 | "jest": "17.0.2", 34 | "json-loader": "0.5.4", 35 | "object-assign": "4.1.0", 36 | "path-exists": "2.1.0", 37 | "postcss-loader": "1.0.0", 38 | "promise": "7.1.1", 39 | "react-dev-utils": "^0.4.2", 40 | "recursive-readdir": "2.1.0", 41 | "status-dev-cli": "^3.2.8", 42 | "strip-ansi": "3.0.1", 43 | "style-loader": "0.13.1", 44 | "truffle-contract": "^1.1.8", 45 | "truffle-solidity-loader": "0.0.8", 46 | "url-loader": "0.5.7", 47 | "webpack": "1.14.0", 48 | "webpack-dev-server": "1.16.2", 49 | "webpack-manifest-plugin": "1.1.0", 50 | "whatwg-fetch": "1.0.0" 51 | }, 52 | "dependencies": { 53 | "axios": "^0.16.2", 54 | "chroma-js": "^1.3.4", 55 | "deep-assign": "^2.0.0", 56 | "dotenv": "^4.0.0", 57 | "ethereumjs-testrpc": "^4.0.1", 58 | "material-ui": "^0.18.7", 59 | "numeral": "^2.0.6", 60 | "query-string": "^4.3.4", 61 | "react": "^15.4.2", 62 | "react-dom": "^15.4.2", 63 | "react-icons": "^2.2.5", 64 | "react-markdown": "^2.5.0", 65 | "react-swipeable-views": "^0.12.5", 66 | "react-tap-event-plugin": "^2.0.1", 67 | "react-vis": "^1.7.1", 68 | "react-youtube": "^7.4.0", 69 | "scrypt": "^6.0.3", 70 | "zeppelin-solidity": "1.7.0" 71 | }, 72 | "scripts": { 73 | "start": "node scripts/start.js", 74 | "build": "node scripts/build.js", 75 | "test": "node scripts/test.js --env=jsdom", 76 | "deploy": "npm run build&&gh-pages -d build" 77 | }, 78 | "jest": { 79 | "collectCoverageFrom": [ 80 | "src/**/*.{js,jsx}" 81 | ], 82 | "setupFiles": [ 83 | "\\config\\polyfills.js" 84 | ], 85 | "testPathIgnorePatterns": [ 86 | "[/\\\\](build|docs|node_modules)[/\\\\]" 87 | ], 88 | "testEnvironment": "node", 89 | "testURL": "http://localhost", 90 | "transform": { 91 | "^.+\\.(js|jsx)$": "/node_modules/babel-jest", 92 | "^.+\\.css$": "\\config\\jest\\cssTransform.js", 93 | "^(?!.*\\.(js|jsx|css|json)$)": "\\config\\jest\\fileTransform.js" 94 | }, 95 | "transformIgnorePatterns": [ 96 | "[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$" 97 | ], 98 | "moduleNameMapper": { 99 | "^react-native$": "react-native-web" 100 | } 101 | }, 102 | "babel": { 103 | "presets": [ 104 | "react-app" 105 | ] 106 | }, 107 | "eslintConfig": { 108 | "extends": "react-app" 109 | }, 110 | "homepage": "https://uummproject.github.io/uumm-prototype/", 111 | "description": "_The Ultimate Unicorn Maker Machine_", 112 | "main": "DeconstructionGovernanceExamples.js", 113 | "directories": { 114 | "doc": "docs", 115 | "test": "test" 116 | }, 117 | "repository": { 118 | "type": "git", 119 | "url": "git+https://github.com/UummProject/uumm-prototype.git" 120 | }, 121 | "keywords": [], 122 | "author": "", 123 | "license": "ISC", 124 | "bugs": { 125 | "url": "https://github.com/UummProject/uumm-prototype/issues" 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/ProposalsList.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ProposalCard from './ProposalCard'; 3 | import UnconfirmedProposalCard from './UnconfirmedProposalCard'; 4 | import Uumm from './UummContractInterface.js' 5 | import State from './State.js' 6 | import Divider from 'material-ui/Divider'; 7 | 8 | class ProposalsList extends React.Component 9 | { 10 | constructor(props) 11 | { 12 | super(); 13 | this.state = {}; 14 | Uumm.isReady().then(()=>{ 15 | Uumm.getProposals(props.projectId) 16 | }) 17 | } 18 | 19 | onPositiveVote = (proposalData)=> 20 | { 21 | Uumm.voteProposal(this.props.projectId, proposalData.id, true) 22 | } 23 | 24 | onNegativeVote = (proposalData)=> 25 | { 26 | Uumm.voteProposal(this.props.projectId, proposalData.id, false) 27 | } 28 | 29 | onResolve = (proposalData)=> 30 | { 31 | Uumm.resolveProposal(this.props.projectId, proposalData.id) 32 | } 33 | 34 | onProposalTitleClicked = (proposalData)=> 35 | { 36 | let extendedProposalId = -1 37 | if(proposalData.id !== this.state.extendedProposalId) 38 | extendedProposalId = proposalData.id 39 | 40 | this.setState({extendedProposalId : extendedProposalId}) 41 | } 42 | 43 | render() 44 | { 45 | var projectData = State.getEmptyProject() 46 | 47 | if(State.data.projects[this.props.projectId]) 48 | projectData = State.data.projects[this.props.projectId] 49 | 50 | var proposalsComponents = []; 51 | 52 | if(projectData.proposals) 53 | { 54 | 55 | for (var proposalId in projectData.proposals) 56 | { 57 | if (!projectData.proposals.hasOwnProperty(proposalId)) 58 | continue 59 | 60 | var proposalData = State.getEmptyProposal() 61 | 62 | if(projectData.proposals[proposalId]) 63 | proposalData = projectData.proposals[proposalId] 64 | 65 | proposalsComponents.push( 66 | ); 78 | 79 | proposalsComponents.push() 80 | } 81 | } 82 | 83 | if(projectData.unconfirmedProposals) 84 | { 85 | for (var unconfirmedProposalId in projectData.unconfirmedProposals) 86 | { 87 | if (!projectData.unconfirmedProposals.hasOwnProperty(unconfirmedProposalId)) 88 | continue 89 | 90 | var unconfirmedProposalData = State.getEmptyProposal() 91 | 92 | if(projectData.unconfirmedProposals[unconfirmedProposalId]) 93 | unconfirmedProposalData = projectData.unconfirmedProposals[unconfirmedProposalId] 94 | 95 | proposalsComponents.push( 96 | ); 103 | 104 | proposalsComponents.push() 105 | 106 | } 107 | } 108 | 109 | return ( 110 |
111 | {proposalsComponents} 112 |
113 | ); 114 | } 115 | } 116 | 117 | export default ProposalsList; -------------------------------------------------------------------------------- /test/VotingData.js: -------------------------------------------------------------------------------- 1 | const ProposalState = 2 | { 3 | PENDING:0, 4 | APPROVED:1, 5 | DENIED:2, 6 | EXPIRED:3 7 | } 8 | 9 | exports.proposals = 10 | [ 11 | { 12 | id:0, 13 | author:"", 14 | title:"This is a 32 characthers title!!", 15 | reference:"This is a 35 characthers reference!!", 16 | valueAmount:9, 17 | creationTimestamp:0, 18 | stateData:[ 19 | { 20 | //#0 Initial state 21 | state:ProposalState.PENDING, 22 | positiveVotes:0, 23 | negativeVotes:0, 24 | totalSupply:1, 25 | contributorVotes:[0]//Represents the list of contributors, indexes matches accounts[] 26 | }, 27 | { 28 | //#1 ProjectCreator (1 token) voted to approve 29 | state:ProposalState.PENDING, 30 | positiveVotes:1, 31 | negativeVotes:0, 32 | totalSupply:1, 33 | contributorVotes:[1] 34 | }, 35 | { 36 | //#2 ProjectCreator (1 token) voted to approve(again). 37 | //Data stays the same 38 | state:ProposalState.PENDING, 39 | positiveVotes:1, 40 | negativeVotes:0, 41 | totalSupply:1, 42 | contributorVotes:[1] 43 | }, 44 | { 45 | //#3 ProjectCreator (1 token) voted against. 46 | //Postive vote goes back to zero, negative to one 47 | state:ProposalState.PENDING, 48 | positiveVotes:0, 49 | negativeVotes:1, 50 | totalSupply:1, 51 | contributorVotes:[-1] 52 | }, 53 | { 54 | //#4 ProjectCreator (1 token) voted in favor. 55 | //Negative vote goes back to zero, positive to one 56 | state:ProposalState.PENDING, 57 | positiveVotes:1, 58 | negativeVotes:0, 59 | totalSupply:1, 60 | contributorVotes:[1] 61 | }, 62 | { 63 | //#5 Proposal is resolved and approved 64 | //State changes from PENDING to APPROVED 65 | //The totalSupply in the proposal remains the same 66 | state:ProposalState.APPROVED, 67 | positiveVotes:1, 68 | negativeVotes:0, 69 | totalSupply:1, 70 | contributorVotes:[1] 71 | } 72 | ] 73 | }, 74 | { 75 | //Proposal[1]. Done by contributor1 76 | id:1, 77 | author:"", 78 | title:"Second proposal title", 79 | reference:"Proposal 2 Reference", 80 | valueAmount:30, 81 | creationTimestamp:0, 82 | stateData:[ 83 | { 84 | //#0 Initial state 85 | //Token supply is updated because of previous proposal (1+9) 86 | state:ProposalState.PENDING, 87 | positiveVotes:0, 88 | negativeVotes:0, 89 | totalSupply:10, 90 | contributorVotes:[0] 91 | }, 92 | { 93 | //#1 Project creator voted (10 tokens) 94 | state:ProposalState.PENDING, 95 | positiveVotes:10, 96 | negativeVotes:0, 97 | totalSupply:10, 98 | contributorVotes:[10] 99 | }, 100 | { 101 | //#2 Project creator resolved (10 tokens) 102 | state:ProposalState.APPROVED, 103 | positiveVotes:10, 104 | negativeVotes:0, 105 | totalSupply:10, 106 | contributorVotes:[10] 107 | }, 108 | ] 109 | } 110 | ] 111 | 112 | exports.contributors = 113 | [ 114 | { 115 | //First contributor is empty 116 | id:0, 117 | contributorAddress:"", 118 | name:"", 119 | valueTokens:0, 120 | etherBalance:0 121 | }, 122 | { 123 | id:1, 124 | contributorAddress:"", 125 | name:"", 126 | valueTokens:10, 127 | etherBalance:0.25 128 | }, 129 | { 130 | id:2, 131 | contributorAddress:"", 132 | name:"", 133 | valueTokens:30, 134 | etherBalance:0.75 135 | } 136 | ] 137 | 138 | -------------------------------------------------------------------------------- /src/fonts/Oswald-300/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2016 The Oswald Project Authors (contact@sansoxygen.com) 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /test/Funding.js: -------------------------------------------------------------------------------- 1 | /*var Uumm = artifacts.require("./Uumm.sol") 2 | var Web3 = new (require("web3")) 3 | 4 | var Validators = require("./Validators.js") 5 | 6 | const addressBook= 7 | { 8 | PROJECT_CREATOR:0, 9 | CONTRIBUTOR1: 1, 10 | CONTRIBUTOR2: 2, 11 | CONTRIBUTOR3: 3, 12 | RANDOM_USER:9 //Never writes (only calls, no transfers) 13 | } 14 | 15 | contract('Uumm', async function(accounts) 16 | { 17 | 18 | getAddress=(index)=> 19 | { 20 | return accounts[index] 21 | } 22 | 23 | const proposals = 24 | [ 25 | { 26 | id:0, 27 | title:"P0,", 28 | reference:"R", 29 | valueAmount:100, 30 | address: getAddress(addressBook.PROJECT_CREATOR), 31 | }, 32 | { 33 | id:1, 34 | title:"P1,", 35 | reference:"R", 36 | valueAmount:1, 37 | address: accounts[1] 38 | }, 39 | { 40 | id:2, 41 | title:"P2,", 42 | reference:"R", 43 | valueAmount:1, 44 | address: accounts[2] 45 | }, 46 | { 47 | id:3, 48 | title:"P3,", 49 | reference:"R", 50 | valueAmount:1, 51 | address: accounts[3] 52 | }, 53 | { 54 | id:4, 55 | title:"P4,", 56 | reference:"R", 57 | valueAmount:1, 58 | address: accounts[4] 59 | }, 60 | { 61 | id:5, 62 | title:"P5,", 63 | reference:"R", 64 | valueAmount:1, 65 | address: accounts[5] 66 | }, 67 | { 68 | id:6, 69 | title:"P6,", 70 | reference:"R", 71 | valueAmount:1, 72 | address: accounts[6] 73 | }, 74 | { 75 | id:7, 76 | title:"P7,", 77 | reference:"R", 78 | valueAmount:1, 79 | address: accounts[7] 80 | }, 81 | { 82 | id:8, 83 | title:"P8,", 84 | reference:"R", 85 | valueAmount:1, 86 | address: accounts[8] 87 | } 88 | 89 | ] 90 | 91 | const contributors = 92 | [ 93 | { 94 | //First contributor is empty 95 | id:0, 96 | contributorAddress:"", 97 | name:"", 98 | valueTokens:0, 99 | etherBalance:0 100 | }, 101 | { 102 | id:1, 103 | contributorAddress:"", 104 | name:"", 105 | valueTokens:10, 106 | etherBalance:0.25 107 | }, 108 | { 109 | id:2, 110 | contributorAddress:"", 111 | name:"", 112 | valueTokens:30, 113 | etherBalance:0.75 114 | } 115 | ] 116 | 117 | getAddress(addressBook.PROJECT_CREATOR) 118 | 119 | let uummInstance = await Uumm.deployed() 120 | await uummInstance.CreateProject("A name", {from: getAddress(addressBook.PROJECT_CREATOR)}) 121 | 122 | let project1Id = await uummInstance.GetProjectId(getAddress(addressBook.PROJECT_CREATOR), 0, {from: getAddress(addressBook.RANDOM_USER)}) 123 | 124 | for(let i = 0; i{ 23 | this.setState({ 24 | "loaded":true, 25 | "connected": true, 26 | "userAddress":Web3AutoSetup.currentAccount, 27 | "provider":Web3AutoSetup.getProviderInfo(), 28 | "network": Web3AutoSetup.getCurrentNetwork().name 29 | }) 30 | 31 | }).catch((error)=>{ 32 | this.setState({ 33 | "loaded":true, 34 | "connected": false}) 35 | console.error(error) 36 | }) 37 | 38 | Web3AutoSetup.addAccountChangedListener(this.onAddressChange) 39 | Web3AutoSetup.addNetworkChangedListener(this.onNetworkChange) 40 | } 41 | 42 | onAddressChange=(newAddress)=> 43 | { 44 | console.log(newAddress) 45 | this.setState({ 46 | "provider":Web3AutoSetup.getProviderInfo(), 47 | "userAddress":newAddress}) 48 | } 49 | 50 | onNetworkChange=(newNetworkId)=> 51 | { 52 | this.setState({ "network":Web3AutoSetup.getCurrentNetwork().name}) 53 | } 54 | 55 | getSmallHint=(text)=> 56 | { 57 | return ( 58 |
59 |

{text}

60 |
61 |
) 62 | } 63 | 64 | getInfuraHint=()=> 65 | { 66 | var exampleLink="https://uummproject.github.io/uumm-prototype/##projectId=0x1568dca1bef08d48017f034930c853bd9487ba947eb58fd51db9979e6de638f9" 67 | var infuraLink ="https://infura.io/" 68 | return ( 69 |

You're connected to ethereum using {"Infura gateway"}

70 |

This means that you can only read the content of already existing projects, {"Like this one"}

71 |

If you want to create a project or participate in one, we suggest you to {"install MetaMask"} browser extension

72 |
) 73 | } 74 | 75 | getNoConnectionHint=()=> 76 | { 77 | return( 78 |

Unable to connect to the Ethereum blockchain

79 | 80 |
) 81 | } 82 | 83 | getNoProviderHint=()=> 84 | { 85 | var video =