From 1da017aa62f30f125d04cda44e7fa535b2e8b1bb Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sun, 12 Aug 2018 10:10:38 -0700 Subject: [PATCH 01/33] Checkpoint --- contracts/Susu.sol | 121 +++------------------------------- contracts/SusuDataStore.sol | 10 +++ contracts/SusuOrig.sol | 126 ++++++++++++++++++++++++++++++++++++ migrations/2_deploy_susu.js | 2 +- test/TestSusu.js | 2 +- 5 files changed, 147 insertions(+), 114 deletions(-) create mode 100644 contracts/SusuDataStore.sol create mode 100644 contracts/SusuOrig.sol diff --git a/contracts/Susu.sol b/contracts/Susu.sol index 772a666..e39a912 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -1,26 +1,17 @@ -pragma solidity ^0.4.22; +pragma solidity 0.4.22; import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; +import "./SusuDataStore.sol" -// API Design here: https://docs.google.com/presentation/d/12qfLPD88TTfvQxWLRTu5boEav8-JdRf3IjpS5WNDTvs/edit#slide=id.g3cb5a7885c_0_11 -// Design Requirements here: https://docs.google.com/document/d/1myfOSSwCPx16uUMSLbtf5RvfLFN97vmkKxjFWIvAaEM/edit -contract Susu is Ownable { +contract Susu { - using SafeMath for uint; + address public susuDataStore; + uint8 constant public MAX_MEMBERS = 5; - string public groupName; - uint256 public contribAmtWei; - uint8 public groupSize; - address[] public members; - uint public memberIdxToPayNext; - uint8 public maxMembers; - mapping(address => uint) private currentContributions; - - constructor(uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { - // Max number of members is 100. Arbitrary but should be smaller than max of uint8 - maxMembers = 100; - require(_groupSize < maxMembers); + constructor(address _susuDataStore, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { + require(_groupSize < MAX_MEMBERS); + susuDataStore = _susuDataStore; groupName = _groupName; contribAmtWei = _contribAmtWei; groupSize = _groupSize; @@ -28,99 +19,5 @@ contract Susu is Ownable { memberIdxToPayNext = 0; } - function payOut() public payable onlyOwner { - if(everyonePaid()) { - resetBalances(); - paySusu(); - iterateMemberToPayNext(); - } - } - - function pullPayOut() public payable { - require(msg.sender == members[memberIdxToPayNext]); - resetBalances(); - iterateMemberToPayNext(); - msg.sender.transfer(members.length * contribAmtWei); - } - - function everyonePaid() private view returns (bool) { - for (uint i = 0; i < members.length ; i++) - { - if(currentContributions[members[i]] != contribAmtWei) - return false; - } - return true; - } - - function resetBalances() private { - for (uint i = 0; i < members.length ; i++) - { - currentContributions[members[i]] = 0; - } - } - - function iterateMemberToPayNext() private { - for (uint i = 0; i < members.length ; i++) - { - if(members[i] == members[memberIdxToPayNext]) { - if(i < members.length - 1) { - memberIdxToPayNext = i.add(1); - return; - } - - memberIdxToPayNext = 0; - return; - } - } - } - - function paySusu() private { - members[memberIdxToPayNext].transfer(members.length * contribAmtWei); - } - - function getMemberAtIndex(uint8 index) public view returns(address) { - return members[index]; - } - - function getContributionForMember(address _member) public view returns(uint256) { - return currentContributions[_member]; - } - - function amIOwner() public view returns(bool) { - return (msg.sender == owner); - } - - function getManyMembers() public view returns(uint) { - return members.length; - } - - function joinGroup() public { - require(!isRecipient(msg.sender)); - members.push(msg.sender); - } - - function contribute() public payable { - require(msg.value == contribAmtWei); - require(isRecipient(msg.sender)); - TrackPayment(); - } - - function TrackPayment() private { - require(currentContributions[msg.sender] == 0); - currentContributions[msg.sender] = msg.value; - } - - function isRecipient(address addr) private view returns (bool) { - for (uint i = 0; i < members.length ; i++) - { - if(members[i] == addr) - return true; - } - return false; - } - - function () external payable { - contribute(); - } -} \ No newline at end of file +} diff --git a/contracts/SusuDataStore.sol b/contracts/SusuDataStore.sol new file mode 100644 index 0000000..ce91dde --- /dev/null +++ b/contracts/SusuDataStore.sol @@ -0,0 +1,10 @@ +pragma solidity 0.4.22; + +contract SusuDataStore { + string public groupName; + uint256 public contribAmtWei; + uint8 public groupSize; + address[] public members; + uint public memberIdxToPayNext; + mapping(address => uint) public currentContributions; +} diff --git a/contracts/SusuOrig.sol b/contracts/SusuOrig.sol new file mode 100644 index 0000000..9818a72 --- /dev/null +++ b/contracts/SusuOrig.sol @@ -0,0 +1,126 @@ +pragma solidity ^0.4.22; + +import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; +import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; + +// API Design here: https://docs.google.com/presentation/d/12qfLPD88TTfvQxWLRTu5boEav8-JdRf3IjpS5WNDTvs/edit#slide=id.g3cb5a7885c_0_11 +// Design Requirements here: https://docs.google.com/document/d/1myfOSSwCPx16uUMSLbtf5RvfLFN97vmkKxjFWIvAaEM/edit +contract SusuOrig is Ownable { + + using SafeMath for uint; + + string public groupName; + uint256 public contribAmtWei; + uint8 public groupSize; + address[] public members; + uint public memberIdxToPayNext; + uint8 public maxMembers; + mapping(address => uint) private currentContributions; + + constructor(uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { + // Max number of members is 100. Arbitrary but should be smaller than max of uint8 + maxMembers = 100; + require(_groupSize < maxMembers); + groupName = _groupName; + contribAmtWei = _contribAmtWei; + groupSize = _groupSize; + members.push(owner); + memberIdxToPayNext = 0; + } + + function payOut() public payable onlyOwner { + if(everyonePaid()) { + resetBalances(); + paySusu(); + iterateMemberToPayNext(); + } + } + + function pullPayOut() public payable { + require(msg.sender == members[memberIdxToPayNext]); + resetBalances(); + iterateMemberToPayNext(); + msg.sender.transfer(members.length * contribAmtWei); + } + + function everyonePaid() private view returns (bool) { + for (uint i = 0; i < members.length ; i++) + { + if(currentContributions[members[i]] != contribAmtWei) + return false; + } + return true; + } + + function resetBalances() private { + for (uint i = 0; i < members.length ; i++) + { + currentContributions[members[i]] = 0; + } + } + + function iterateMemberToPayNext() private { + for (uint i = 0; i < members.length ; i++) + { + if(members[i] == members[memberIdxToPayNext]) { + if(i < members.length - 1) { + memberIdxToPayNext = i.add(1); + return; + } + + memberIdxToPayNext = 0; + return; + } + } + } + + function paySusu() private { + members[memberIdxToPayNext].transfer(members.length * contribAmtWei); + } + + function getMemberAtIndex(uint8 index) public view returns(address) { + return members[index]; + } + + function getContributionForMember(address _member) public view returns(uint256) { + return currentContributions[_member]; + } + + function amIOwner() public view returns(bool) { + return (msg.sender == owner); + } + + function getManyMembers() public view returns(uint) { + return members.length; + } + + function joinGroup() public { + require(!isRecipient(msg.sender)); + members.push(msg.sender); + } + + function contribute() public payable { + require(msg.value == contribAmtWei); + require(isRecipient(msg.sender)); + + TrackPayment(); + } + + function TrackPayment() private { + require(currentContributions[msg.sender] == 0); + currentContributions[msg.sender] = msg.value; + } + + function isRecipient(address addr) private view returns (bool) { + for (uint i = 0; i < members.length ; i++) + { + if(members[i] == addr) + return true; + } + return false; + } + + function () external payable { + contribute(); + } +} \ No newline at end of file diff --git a/migrations/2_deploy_susu.js b/migrations/2_deploy_susu.js index b70d302..0957c5b 100644 --- a/migrations/2_deploy_susu.js +++ b/migrations/2_deploy_susu.js @@ -1,4 +1,4 @@ -var Susu = artifacts.require("./Susu.sol"); +var Susu = artifacts.require("./SusuOrig.sol"); module.exports = function (deployer) { deployer.deploy(Susu, 2, "Test", 1); diff --git a/test/TestSusu.js b/test/TestSusu.js index 2db17b1..cb2fd7d 100644 --- a/test/TestSusu.js +++ b/test/TestSusu.js @@ -1,4 +1,4 @@ -const Susu = artifacts.require('./Susu.sol') +const Susu = artifacts.require('./SusuOrig.sol') contract('Susu', function ([owner, donor]) { let susu From 56d10219d6a52e65e858d64f6d83a0023be76a84 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sun, 12 Aug 2018 10:25:53 -0700 Subject: [PATCH 02/33] make sure SusuOrig still working --- contracts/Susu.sol | 20 +++++----- contracts/SusuDataStore.sol | 2 +- contracts/openZepplin/Ownable.sol | 64 ------------------------------- migrations/2_deploy_susu.js | 5 --- migrations/2_deploy_susu_orig.js | 5 +++ src/components/DeployPage.js | 2 +- src/components/GroupPage.js | 2 +- 7 files changed, 18 insertions(+), 82 deletions(-) delete mode 100644 contracts/openZepplin/Ownable.sol delete mode 100644 migrations/2_deploy_susu.js create mode 100644 migrations/2_deploy_susu_orig.js diff --git a/contracts/Susu.sol b/contracts/Susu.sol index e39a912..86464b4 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -1,22 +1,22 @@ -pragma solidity 0.4.22; +pragma solidity ^0.4.22; import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; -import "./SusuDataStore.sol" +import "./SusuDataStore.sol"; contract Susu { - address public susuDataStore; + SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - constructor(address _susuDataStore, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { + constructor(address _susuDataStoreAddress, uint8 _groupSize) public { require(_groupSize < MAX_MEMBERS); - susuDataStore = _susuDataStore; - groupName = _groupName; - contribAmtWei = _contribAmtWei; - groupSize = _groupSize; - members.push(owner); - memberIdxToPayNext = 0; + susuDataStore = SusuDataStore(_susuDataStoreAddress); +// groupName = _groupName; +// contribAmtWei = _contribAmtWei; +// groupSize = _groupSize; +// members.push(owner); +// memberIdxToPayNext = 0; } diff --git a/contracts/SusuDataStore.sol b/contracts/SusuDataStore.sol index ce91dde..7515e48 100644 --- a/contracts/SusuDataStore.sol +++ b/contracts/SusuDataStore.sol @@ -1,4 +1,4 @@ -pragma solidity 0.4.22; +pragma solidity ^0.4.22; contract SusuDataStore { string public groupName; diff --git a/contracts/openZepplin/Ownable.sol b/contracts/openZepplin/Ownable.sol deleted file mode 100644 index 1fbf571..0000000 --- a/contracts/openZepplin/Ownable.sol +++ /dev/null @@ -1,64 +0,0 @@ -pragma solidity ^0.4.24; - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - event OwnershipRenounced(address indexed previousOwner); - event OwnershipTransferred( - address indexed previousOwner, - address indexed newOwner - ); - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - /** - * @dev Allows the current owner to relinquish control of the contract. - * @notice Renouncing to ownership will leave the contract without an owner. - * It will not be possible to call the functions with the `onlyOwner` - * modifier anymore. - */ - function renounceOwnership() public onlyOwner { - emit OwnershipRenounced(owner); - owner = address(0); - } - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param _newOwner The address to transfer ownership to. - */ - function transferOwnership(address _newOwner) public onlyOwner { - _transferOwnership(_newOwner); - } - - /** - * @dev Transfers control of the contract to a newOwner. - * @param _newOwner The address to transfer ownership to. - */ - function _transferOwnership(address _newOwner) internal { - require(_newOwner != address(0)); - emit OwnershipTransferred(owner, _newOwner); - owner = _newOwner; - } -} diff --git a/migrations/2_deploy_susu.js b/migrations/2_deploy_susu.js deleted file mode 100644 index 0957c5b..0000000 --- a/migrations/2_deploy_susu.js +++ /dev/null @@ -1,5 +0,0 @@ -var Susu = artifacts.require("./SusuOrig.sol"); - -module.exports = function (deployer) { - deployer.deploy(Susu, 2, "Test", 1); -}; diff --git a/migrations/2_deploy_susu_orig.js b/migrations/2_deploy_susu_orig.js new file mode 100644 index 0000000..c9d559b --- /dev/null +++ b/migrations/2_deploy_susu_orig.js @@ -0,0 +1,5 @@ +var SusuOrig = artifacts.require("./SusuOrig.sol"); + +module.exports = function (deployer) { + deployer.deploy(SusuOrig, 2, "Test", 1); +}; diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index 177c20a..2ea4227 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -1,7 +1,7 @@ import React, { Component } from 'react' import contract from 'truffle-contract' -import SusuContract from '../../build/contracts/Susu.json' +import SusuContract from '../../build/contracts/SusuOrig.json' import getWeb3 from '../utils/getWeb3' import '../App.css' diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index 6fef4a9..e7739c5 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -1,6 +1,6 @@ import React, { Component } from 'react' -import SusuContract from '../../build/contracts/Susu.json' +import SusuContract from '../../build/contracts/SusuOrig.json' import getWeb3 from '../utils/getWeb3' import {BigNumber} from 'bignumber.js'; From 568189a11383234eb43a098b577062c8818d463a Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sun, 12 Aug 2018 10:37:19 -0700 Subject: [PATCH 03/33] start SusuParent --- contracts/Susu.sol | 10 +++------- contracts/SusuDataStore.sol | 10 +++++++++- contracts/SusuParent.sol | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 contracts/SusuParent.sol diff --git a/contracts/Susu.sol b/contracts/Susu.sol index 86464b4..4417159 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -9,14 +9,10 @@ contract Susu { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - constructor(address _susuDataStoreAddress, uint8 _groupSize) public { - require(_groupSize < MAX_MEMBERS); + constructor(address _susuDataStoreAddress) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); -// groupName = _groupName; -// contribAmtWei = _contribAmtWei; -// groupSize = _groupSize; -// members.push(owner); -// memberIdxToPayNext = 0; + require(susuDataStore.groupSize() <= MAX_MEMBERS); + //members.push(owner); } diff --git a/contracts/SusuDataStore.sol b/contracts/SusuDataStore.sol index 7515e48..d3b4a19 100644 --- a/contracts/SusuDataStore.sol +++ b/contracts/SusuDataStore.sol @@ -5,6 +5,14 @@ contract SusuDataStore { uint256 public contribAmtWei; uint8 public groupSize; address[] public members; - uint public memberIdxToPayNext; + uint public memberIdxToPayNext = 0; mapping(address => uint) public currentContributions; + + constructor(uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { + groupName = _groupName; + contribAmtWei = _contribAmtWei; + groupSize = _groupSize; + } + + } diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol new file mode 100644 index 0000000..3c5f191 --- /dev/null +++ b/contracts/SusuParent.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.4.22; + +import "./Susu.sol"; +import "./SusuDataStore.sol"; + +contract SusuParent { + + mapping(bytes32 => address) public deployedSusus; + + function createSusu(bytes32 key_, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { + address susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); + address susu = new Susu(susuDataStore); + deployedSusus[key_] = susu; + } +} From d71ff5f64741da813790bf7eeb65b370ff859063 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sun, 12 Aug 2018 10:43:40 -0700 Subject: [PATCH 04/33] instantiateParentContract --- migrations/3_deploy_susu_parent.js | 5 +++++ src/components/GroupPage.js | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 migrations/3_deploy_susu_parent.js diff --git a/migrations/3_deploy_susu_parent.js b/migrations/3_deploy_susu_parent.js new file mode 100644 index 0000000..7f90965 --- /dev/null +++ b/migrations/3_deploy_susu_parent.js @@ -0,0 +1,5 @@ +var SusuParent = artifacts.require("./SusuParent.sol"); + +module.exports = function (deployer) { + deployer.deploy(SusuParent); +}; diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index e7739c5..4687c26 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -1,6 +1,7 @@ import React, { Component } from 'react' import SusuContract from '../../build/contracts/SusuOrig.json' +import SusuParentContract from '../../build/contracts/SusuParent.json' import getWeb3 from '../utils/getWeb3' import {BigNumber} from 'bignumber.js'; @@ -21,6 +22,7 @@ class GroupPage extends Component { this.state = { web3: null, susuContract: null, + susuParentContract: null, myAddress: '', contribAmt: 0, groupName: '---', @@ -44,12 +46,23 @@ class GroupPage extends Component { // Instantiate contract once web3 provided. this.instantiateContract(); + this.instantiateParentContract(); }) .catch((err) => { console.log('Error finding web3. err:',err); }) } + instantiateParentContract() { + const susuParentContract = this.state.web3.eth.contract(SusuParentContract.abi).at(this.state.contractAddress); + this.setState({susuParentContract:susuParentContract}); + console.log('susuParentContract:',susuParentContract); + + // susuParentContract.groupName((err, groupName)=>{ + // this.setState({groupName:groupName}); + // }); + } + instantiateContract() { const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(this.state.contractAddress); this.setState({susuContract:susuContract}); @@ -127,6 +140,7 @@ class GroupPage extends Component { return (
+
@@ -156,6 +170,11 @@ class GroupPage extends Component { ); }// render() + testSusuParent(e) { + e.preventDefault(); + console.log('click'); + } + isReadyToPayout() { if(this.state.manyMembers===this.state.groupSize) { for(let partnerObj of this.state.partnerObjects) { From 6da228db78acad18f5631acfddb7bba9c581e8fe Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sun, 12 Aug 2018 16:26:22 -0700 Subject: [PATCH 05/33] createSusu is called --- contracts/SusuParent.sol | 7 ++++--- src/components/GroupPage.js | 31 ++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index 3c5f191..f75b727 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -6,10 +6,11 @@ import "./SusuDataStore.sol"; contract SusuParent { mapping(bytes32 => address) public deployedSusus; + string public foo = "bar"; function createSusu(bytes32 key_, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { - address susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); - address susu = new Susu(susuDataStore); - deployedSusus[key_] = susu; +// address susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); +// address susu = new Susu(susuDataStore); +// deployedSusus[key_] = susu; } } diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index 4687c26..b2e2fc4 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -46,7 +46,6 @@ class GroupPage extends Component { // Instantiate contract once web3 provided. this.instantiateContract(); - this.instantiateParentContract(); }) .catch((err) => { console.log('Error finding web3. err:',err); @@ -54,15 +53,27 @@ class GroupPage extends Component { } instantiateParentContract() { - const susuParentContract = this.state.web3.eth.contract(SusuParentContract.abi).at(this.state.contractAddress); - this.setState({susuParentContract:susuParentContract}); - console.log('susuParentContract:',susuParentContract); - - // susuParentContract.groupName((err, groupName)=>{ - // this.setState({groupName:groupName}); - // }); + const contract = require("truffle-contract"); + const MyContract = contract(SusuParentContract); + const provider = new this.state.web3.providers.HttpProvider("http://localhost:7545"); + MyContract.setProvider(provider); + + MyContract.deployed().then(function(instance) { + // console.log('instance:',instance); + // const key = 'this is a key'; + // const groupSize = 4; + // const groupName = 'newName'; + // const contribAmtWei = 10000000000000; + return instance.createSusu.call('key', 2, 'name', 1); + }).then((r)=>{console.log('r:',r);}); } + // susuParentCallback() { + // return (err, result) => { + // console.log('err:',err,' result:',result); + // } + // } + instantiateContract() { const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(this.state.contractAddress); this.setState({susuContract:susuContract}); @@ -92,10 +103,8 @@ class GroupPage extends Component { susuContract.memberIdxToPayNext((err, memberIdxToPayNextBig)=>{ let bigNumber = new BigNumber(memberIdxToPayNextBig); const memberIdxToPayNext = bigNumber.toNumber(); - console.log('memberIdxToPayNext:',memberIdxToPayNext); susuContract.getMemberAtIndex(memberIdxToPayNext, (err, memberAddrToPayNext)=>{ - console.log('memberAddrToPayNext:',memberAddrToPayNext); this.setState({memberAddrToPayNext:memberAddrToPayNext}); }); }); @@ -172,7 +181,7 @@ class GroupPage extends Component { testSusuParent(e) { e.preventDefault(); - console.log('click'); + this.instantiateParentContract(); } isReadyToPayout() { From 8167f121eb5f3a7d338ee9352f60c79b51429e4a Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sun, 12 Aug 2018 16:38:37 -0700 Subject: [PATCH 06/33] Susu stuff --- contracts/SusuParent.sol | 9 +++++---- src/components/GroupPage.js | 22 ++++++++-------------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index f75b727..7ae94b8 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -8,9 +8,10 @@ contract SusuParent { mapping(bytes32 => address) public deployedSusus; string public foo = "bar"; - function createSusu(bytes32 key_, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { -// address susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); -// address susu = new Susu(susuDataStore); -// deployedSusus[key_] = susu; + function createSusu(bytes32 key_, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public returns(address){ + address susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); + address susu = new Susu(susuDataStore); + deployedSusus[key_] = susu; + return susu; } } diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index b2e2fc4..6206914 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -1,7 +1,8 @@ import React, { Component } from 'react' -import SusuContract from '../../build/contracts/SusuOrig.json' +import SusuOrigContract from '../../build/contracts/SusuOrig.json' import SusuParentContract from '../../build/contracts/SusuParent.json' +import SusuContract from '../../build/contracts/Susu.json' import getWeb3 from '../utils/getWeb3' import {BigNumber} from 'bignumber.js'; @@ -59,23 +60,16 @@ class GroupPage extends Component { MyContract.setProvider(provider); MyContract.deployed().then(function(instance) { - // console.log('instance:',instance); - // const key = 'this is a key'; - // const groupSize = 4; - // const groupName = 'newName'; - // const contribAmtWei = 10000000000000; return instance.createSusu.call('key', 2, 'name', 1); - }).then((r)=>{console.log('r:',r);}); + }).then((susuContractAddress)=>{ + console.log('susuContractAddress:',susuContractAddress); + const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); + console.log('susuContract:',susuContract); + }); } - // susuParentCallback() { - // return (err, result) => { - // console.log('err:',err,' result:',result); - // } - // } - instantiateContract() { - const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(this.state.contractAddress); + const susuContract = this.state.web3.eth.contract(SusuOrigContract.abi).at(this.state.contractAddress); this.setState({susuContract:susuContract}); let _this = this; From f980bff5fbb005247a229c97de0bb03abb39298e Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sun, 12 Aug 2018 17:17:40 -0700 Subject: [PATCH 07/33] Use deployed --- contracts/Susu.sol | 7 +++++-- contracts/SusuDataStore.sol | 7 +++++++ contracts/SusuParent.sol | 11 ++++++++--- src/components/GroupPage.js | 6 ++---- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index 4417159..c80e44c 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -4,7 +4,7 @@ import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; import "./SusuDataStore.sol"; -contract Susu { +contract Susu is Ownable { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; @@ -12,8 +12,11 @@ contract Susu { constructor(address _susuDataStoreAddress) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); require(susuDataStore.groupSize() <= MAX_MEMBERS); - //members.push(owner); + susuDataStore.addMember(owner); } + function getGroupName() public view returns(string) { + return susuDataStore.getGroupName(); + } } diff --git a/contracts/SusuDataStore.sol b/contracts/SusuDataStore.sol index d3b4a19..d2f121b 100644 --- a/contracts/SusuDataStore.sol +++ b/contracts/SusuDataStore.sol @@ -14,5 +14,12 @@ contract SusuDataStore { groupSize = _groupSize; } + function addMember(address _member) public returns(address[]){ + members.push(_member); + } + + function getGroupName() public view returns(string) { + return groupName; + } } diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index 7ae94b8..f533083 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -8,10 +8,15 @@ contract SusuParent { mapping(bytes32 => address) public deployedSusus; string public foo = "bar"; - function createSusu(bytes32 key_, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public returns(address){ + function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { address susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); address susu = new Susu(susuDataStore); - deployedSusus[key_] = susu; - return susu; + deployedSusus[_key] = susu; } + + function getGroupName(bytes32 _key) public view returns(string) { + Susu susu = Susu(deployedSusus[_key]); + return susu.getGroupName(); + } + } diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index 6206914..d4e516f 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -61,10 +61,8 @@ class GroupPage extends Component { MyContract.deployed().then(function(instance) { return instance.createSusu.call('key', 2, 'name', 1); - }).then((susuContractAddress)=>{ - console.log('susuContractAddress:',susuContractAddress); - const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); - console.log('susuContract:',susuContract); + }).then(()=>{ + }); } From 793c11f6a9f18a074c1df9288f0464c018bb822e Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Mon, 13 Aug 2018 20:04:52 -0700 Subject: [PATCH 08/33] getSusu --- contracts/SusuParent.sol | 14 ++++++++++---- src/components/GroupPage.js | 29 ++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index f533083..70044a9 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -8,14 +8,20 @@ contract SusuParent { mapping(bytes32 => address) public deployedSusus; string public foo = "bar"; - function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { - address susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); - address susu = new Susu(susuDataStore); + function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public returns(address) { + SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); + Susu susu = new Susu(susuDataStore); deployedSusus[_key] = susu; + return susu; + } + + function getSusu(bytes32 _key) public constant returns(address) { + return deployedSusus[_key]; } function getGroupName(bytes32 _key) public view returns(string) { - Susu susu = Susu(deployedSusus[_key]); + address susuAddress = deployedSusus[_key]; + Susu susu = Susu(susuAddress); return susu.getGroupName(); } diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index d4e516f..f4abb9e 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -2,7 +2,6 @@ import React, { Component } from 'react' import SusuOrigContract from '../../build/contracts/SusuOrig.json' import SusuParentContract from '../../build/contracts/SusuParent.json' -import SusuContract from '../../build/contracts/Susu.json' import getWeb3 from '../utils/getWeb3' import {BigNumber} from 'bignumber.js'; @@ -56,14 +55,30 @@ class GroupPage extends Component { instantiateParentContract() { const contract = require("truffle-contract"); const MyContract = contract(SusuParentContract); - const provider = new this.state.web3.providers.HttpProvider("http://localhost:7545"); + const provider = new this.state.web3.providers.HttpProvider("http://127.0.0.1:7545"); MyContract.setProvider(provider); - - MyContract.deployed().then(function(instance) { - return instance.createSusu.call('key', 2, 'name', 1); - }).then(()=>{ - + MyContract.deployed().then((instance)=>{ + return instance.createSusu.call('key', 2, 'name', 1).then((response)=>{ + instance.getGroupName.call('key'); + // console.log('instance:',instance); + // return instance.getGroupName.call('key').then((response)=>{ + // console.log('response:',response); + // }); + }); }); + + // MyContract.deployed().then(function(instance) { + // return instance.createSusu('key', 2, 'name', 1).then((response)=>{ + // // console.log('instance:',instance); + // }); + // }); + // .then(()=>{ + // MyContract.deployed().then(function(instance) { + // console.log('instance:',instance); + // // instance.getGroupName('key'); + // // return instance.getGroupName.call('key'); + // }) + // }); } instantiateContract() { From a260c4c55a6b1a8e5187e3324ff3fd68a7947928 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Tue, 14 Aug 2018 10:57:24 -0700 Subject: [PATCH 09/33] Lordy. After all that work and it just starts working. bah. --- src/components/GroupPage.js | 54 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index f4abb9e..42b65f9 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -46,39 +46,19 @@ class GroupPage extends Component { // Instantiate contract once web3 provided. this.instantiateContract(); + this.instantiateSusuContract(); }) .catch((err) => { console.log('Error finding web3. err:',err); }) } - instantiateParentContract() { + instantiateSusuContract() { const contract = require("truffle-contract"); - const MyContract = contract(SusuParentContract); + const susuParentContract = contract(SusuParentContract); const provider = new this.state.web3.providers.HttpProvider("http://127.0.0.1:7545"); - MyContract.setProvider(provider); - MyContract.deployed().then((instance)=>{ - return instance.createSusu.call('key', 2, 'name', 1).then((response)=>{ - instance.getGroupName.call('key'); - // console.log('instance:',instance); - // return instance.getGroupName.call('key').then((response)=>{ - // console.log('response:',response); - // }); - }); - }); - - // MyContract.deployed().then(function(instance) { - // return instance.createSusu('key', 2, 'name', 1).then((response)=>{ - // // console.log('instance:',instance); - // }); - // }); - // .then(()=>{ - // MyContract.deployed().then(function(instance) { - // console.log('instance:',instance); - // // instance.getGroupName('key'); - // // return instance.getGroupName.call('key'); - // }) - // }); + susuParentContract.setProvider(provider); + this.setState({susuParentContract: susuParentContract}); } instantiateContract() { @@ -156,7 +136,9 @@ class GroupPage extends Component { return (
- + + +
@@ -186,9 +168,25 @@ class GroupPage extends Component { ); }// render() - testSusuParent(e) { + createSusu(e) { + e.preventDefault(); + this.state.susuParentContract.deployed().then((instance)=>{ + return instance.createSusu.call('key', 2, 'name', 1); + }).then((result)=>{console.log('result:',result);}); + } + + getSusu(e) { + e.preventDefault(); + this.state.susuParentContract.deployed().then((instance)=>{ + return instance.getSusu.call('key'); + }).then((result)=>{console.log('result:',result);}); + } + + getSusuName(e) { e.preventDefault(); - this.instantiateParentContract(); + this.state.susuParentContract.deployed().then((instance)=>{ + return instance.getGroupName.call('key'); + }).then((result)=>{console.log('result:',result);}); } isReadyToPayout() { From d32b84c9179194672f03a6209c76dff9c3026faf Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Tue, 14 Aug 2018 11:02:05 -0700 Subject: [PATCH 10/33] Move buttons to deploy page --- src/components/DeployPage.js | 37 ++++++++++++++++++++++++++++++++++++ src/components/GroupPage.js | 35 ---------------------------------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index 2ea4227..85c6201 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -5,6 +5,7 @@ import SusuContract from '../../build/contracts/SusuOrig.json' import getWeb3 from '../utils/getWeb3' import '../App.css' +import SusuParentContract from "../../build/contracts/SusuParent"; class DeployPage extends Component { @@ -14,6 +15,7 @@ class DeployPage extends Component { this.state = { web3: null, isLoading: false, + susuParentContract: null, } } @@ -23,12 +25,22 @@ class DeployPage extends Component { this.setState({ web3: results.web3 }); + + this.instantiateSusuContract(); }) .catch(() => { console.log('Error finding web3.'); }) } + instantiateSusuContract() { + const contract = require("truffle-contract"); + const susuParentContract = contract(SusuParentContract); + const provider = new this.state.web3.providers.HttpProvider("http://127.0.0.1:7545"); + susuParentContract.setProvider(provider); + this.setState({susuParentContract: susuParentContract}); + } + render() { const disabled = this.state.isLoading ? 'btn-disabled' : ''; const btnClasses = `${disabled} btn-contribute`; @@ -36,6 +48,9 @@ class DeployPage extends Component {
+ + +
@@ -63,6 +78,28 @@ class DeployPage extends Component { ); }// render() + + createSusu(e) { + e.preventDefault(); + this.state.susuParentContract.deployed().then((instance)=>{ + return instance.createSusu.call('key', 2, 'name', 1); + }).then((result)=>{console.log('result:',result);}); + } + + getSusu(e) { + e.preventDefault(); + this.state.susuParentContract.deployed().then((instance)=>{ + return instance.getSusu.call('key'); + }).then((result)=>{console.log('result:',result);}); + } + + getSusuName(e) { + e.preventDefault(); + this.state.susuParentContract.deployed().then((instance)=>{ + return instance.getGroupName.call('key'); + }).then((result)=>{console.log('result:',result);}); + } + clickCreate(e) { e.preventDefault(); this.setState({isLoading:true}); diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index 42b65f9..46f3a0e 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -1,7 +1,6 @@ import React, { Component } from 'react' import SusuOrigContract from '../../build/contracts/SusuOrig.json' -import SusuParentContract from '../../build/contracts/SusuParent.json' import getWeb3 from '../utils/getWeb3' import {BigNumber} from 'bignumber.js'; @@ -22,7 +21,6 @@ class GroupPage extends Component { this.state = { web3: null, susuContract: null, - susuParentContract: null, myAddress: '', contribAmt: 0, groupName: '---', @@ -46,21 +44,12 @@ class GroupPage extends Component { // Instantiate contract once web3 provided. this.instantiateContract(); - this.instantiateSusuContract(); }) .catch((err) => { console.log('Error finding web3. err:',err); }) } - instantiateSusuContract() { - const contract = require("truffle-contract"); - const susuParentContract = contract(SusuParentContract); - const provider = new this.state.web3.providers.HttpProvider("http://127.0.0.1:7545"); - susuParentContract.setProvider(provider); - this.setState({susuParentContract: susuParentContract}); - } - instantiateContract() { const susuContract = this.state.web3.eth.contract(SusuOrigContract.abi).at(this.state.contractAddress); this.setState({susuContract:susuContract}); @@ -136,9 +125,6 @@ class GroupPage extends Component { return (
- - -
@@ -168,27 +154,6 @@ class GroupPage extends Component { ); }// render() - createSusu(e) { - e.preventDefault(); - this.state.susuParentContract.deployed().then((instance)=>{ - return instance.createSusu.call('key', 2, 'name', 1); - }).then((result)=>{console.log('result:',result);}); - } - - getSusu(e) { - e.preventDefault(); - this.state.susuParentContract.deployed().then((instance)=>{ - return instance.getSusu.call('key'); - }).then((result)=>{console.log('result:',result);}); - } - - getSusuName(e) { - e.preventDefault(); - this.state.susuParentContract.deployed().then((instance)=>{ - return instance.getGroupName.call('key'); - }).then((result)=>{console.log('result:',result);}); - } - isReadyToPayout() { if(this.state.manyMembers===this.state.groupSize) { for(let partnerObj of this.state.partnerObjects) { From e3ac60861ff544ef33d59db913495dbbaa1603a1 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Tue, 14 Aug 2018 18:08:01 -0700 Subject: [PATCH 11/33] Add gas to transaction --- .gitignore | 1 + src/components/DeployPage.js | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7746d6d..98d9cee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .idea +build_webpack build/contracts/* node_modules package-lock.json diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index 85c6201..23ce824 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -82,21 +82,22 @@ class DeployPage extends Component { createSusu(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ - return instance.createSusu.call('key', 2, 'name', 1); + const options = { from: this.state.web3.eth.accounts[0], gas: 1000000 } + return instance.createSusu('key1', 2, 'name', 1, options); }).then((result)=>{console.log('result:',result);}); } getSusu(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ - return instance.getSusu.call('key'); + return instance.getSusu.call('key1'); }).then((result)=>{console.log('result:',result);}); } getSusuName(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ - return instance.getGroupName.call('key'); + return instance.getGroupName.call('key1'); }).then((result)=>{console.log('result:',result);}); } From ed2ee948586dedf12fc70395a8cfe24ef3fd2c41 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Tue, 14 Aug 2018 18:14:31 -0700 Subject: [PATCH 12/33] Rename SusuBizLogi and Susu.sol --- contracts/Susu.sol | 28 +++++++++++++++++----------- contracts/SusuBizLogic.sol | 22 ++++++++++++++++++++++ contracts/SusuParent.sol | 28 ---------------------------- migrations/3_deploy_susu.js | 5 +++++ migrations/3_deploy_susu_parent.js | 5 ----- src/components/DeployPage.js | 20 ++++++++++---------- 6 files changed, 54 insertions(+), 54 deletions(-) create mode 100644 contracts/SusuBizLogic.sol delete mode 100644 contracts/SusuParent.sol create mode 100644 migrations/3_deploy_susu.js delete mode 100644 migrations/3_deploy_susu_parent.js diff --git a/contracts/Susu.sol b/contracts/Susu.sol index c80e44c..3305546 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -1,22 +1,28 @@ pragma solidity ^0.4.22; -import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; -import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; +import "./SusuBizLogic.sol"; import "./SusuDataStore.sol"; -contract Susu is Ownable { +contract Susu { - SusuDataStore public susuDataStore; - uint8 constant public MAX_MEMBERS = 5; + mapping(bytes32 => address) public deployedSusus; + string public foo = "bar"; - constructor(address _susuDataStoreAddress) public { - susuDataStore = SusuDataStore(_susuDataStoreAddress); - require(susuDataStore.groupSize() <= MAX_MEMBERS); - susuDataStore.addMember(owner); + function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public returns(address) { + SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); + SusuBizLogic susu = new SusuBizLogic(susuDataStore); + deployedSusus[_key] = susu; + return susu; } - function getGroupName() public view returns(string) { - return susuDataStore.getGroupName(); + function getSusu(bytes32 _key) public constant returns(address) { + return deployedSusus[_key]; + } + + function getGroupName(bytes32 _key) public view returns(string) { + address susuAddress = deployedSusus[_key]; + SusuBizLogic susu = SusuBizLogic(susuAddress); + return susu.getGroupName(); } } diff --git a/contracts/SusuBizLogic.sol b/contracts/SusuBizLogic.sol new file mode 100644 index 0000000..69e6956 --- /dev/null +++ b/contracts/SusuBizLogic.sol @@ -0,0 +1,22 @@ +pragma solidity ^0.4.22; + +import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; +import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; +import "./SusuDataStore.sol"; + +contract SusuBizLogic is Ownable { + + SusuDataStore public susuDataStore; + uint8 constant public MAX_MEMBERS = 5; + + constructor(address _susuDataStoreAddress) public { + susuDataStore = SusuDataStore(_susuDataStoreAddress); + require(susuDataStore.groupSize() <= MAX_MEMBERS); + susuDataStore.addMember(owner); + } + + function getGroupName() public view returns(string) { + return susuDataStore.getGroupName(); + } + +} diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol deleted file mode 100644 index 70044a9..0000000 --- a/contracts/SusuParent.sol +++ /dev/null @@ -1,28 +0,0 @@ -pragma solidity ^0.4.22; - -import "./Susu.sol"; -import "./SusuDataStore.sol"; - -contract SusuParent { - - mapping(bytes32 => address) public deployedSusus; - string public foo = "bar"; - - function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public returns(address) { - SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); - Susu susu = new Susu(susuDataStore); - deployedSusus[_key] = susu; - return susu; - } - - function getSusu(bytes32 _key) public constant returns(address) { - return deployedSusus[_key]; - } - - function getGroupName(bytes32 _key) public view returns(string) { - address susuAddress = deployedSusus[_key]; - Susu susu = Susu(susuAddress); - return susu.getGroupName(); - } - -} diff --git a/migrations/3_deploy_susu.js b/migrations/3_deploy_susu.js new file mode 100644 index 0000000..da1f00f --- /dev/null +++ b/migrations/3_deploy_susu.js @@ -0,0 +1,5 @@ +var Susu = artifacts.require("./Susu.sol"); + +module.exports = function (deployer) { + deployer.deploy(Susu); +}; diff --git a/migrations/3_deploy_susu_parent.js b/migrations/3_deploy_susu_parent.js deleted file mode 100644 index 7f90965..0000000 --- a/migrations/3_deploy_susu_parent.js +++ /dev/null @@ -1,5 +0,0 @@ -var SusuParent = artifacts.require("./SusuParent.sol"); - -module.exports = function (deployer) { - deployer.deploy(SusuParent); -}; diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index 23ce824..329c218 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -1,11 +1,11 @@ import React, { Component } from 'react' import contract from 'truffle-contract' -import SusuContract from '../../build/contracts/SusuOrig.json' +import SusuOrigContract from '../../build/contracts/SusuOrig.json' import getWeb3 from '../utils/getWeb3' import '../App.css' -import SusuParentContract from "../../build/contracts/SusuParent"; +import SusuContract from "../../build/contracts/Susu"; class DeployPage extends Component { @@ -15,7 +15,7 @@ class DeployPage extends Component { this.state = { web3: null, isLoading: false, - susuParentContract: null, + susuContract: null, } } @@ -35,10 +35,10 @@ class DeployPage extends Component { instantiateSusuContract() { const contract = require("truffle-contract"); - const susuParentContract = contract(SusuParentContract); + const susuContract = contract(SusuContract); const provider = new this.state.web3.providers.HttpProvider("http://127.0.0.1:7545"); - susuParentContract.setProvider(provider); - this.setState({susuParentContract: susuParentContract}); + susuContract.setProvider(provider); + this.setState({susuContract: susuContract}); } render() { @@ -81,7 +81,7 @@ class DeployPage extends Component { createSusu(e) { e.preventDefault(); - this.state.susuParentContract.deployed().then((instance)=>{ + this.state.susuContract.deployed().then((instance)=>{ const options = { from: this.state.web3.eth.accounts[0], gas: 1000000 } return instance.createSusu('key1', 2, 'name', 1, options); }).then((result)=>{console.log('result:',result);}); @@ -89,14 +89,14 @@ class DeployPage extends Component { getSusu(e) { e.preventDefault(); - this.state.susuParentContract.deployed().then((instance)=>{ + this.state.susuContract.deployed().then((instance)=>{ return instance.getSusu.call('key1'); }).then((result)=>{console.log('result:',result);}); } getSusuName(e) { e.preventDefault(); - this.state.susuParentContract.deployed().then((instance)=>{ + this.state.susuContract.deployed().then((instance)=>{ return instance.getGroupName.call('key1'); }).then((result)=>{console.log('result:',result);}); } @@ -104,7 +104,7 @@ class DeployPage extends Component { clickCreate(e) { e.preventDefault(); this.setState({isLoading:true}); - const susuContract = contract(SusuContract); + const susuContract = contract(SusuOrigContract); const { unlinked_binary, abi } = susuContract; const newContract = this.state.web3.eth.contract(abi) const options = { from: this.state.web3.eth.accounts[0], data: unlinked_binary, gas: 2000000 } From 57068805fa27ec1a13e303b6138a77e76cecbf16 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Wed, 15 Aug 2018 09:13:23 -0700 Subject: [PATCH 13/33] Revert "Rename SusuBizLogi and Susu.sol" This reverts commit ed2ee948586dedf12fc70395a8cfe24ef3fd2c41. --- contracts/Susu.sol | 28 +++++++++++----------------- contracts/SusuBizLogic.sol | 22 ---------------------- contracts/SusuParent.sol | 28 ++++++++++++++++++++++++++++ migrations/3_deploy_susu.js | 5 ----- migrations/3_deploy_susu_parent.js | 5 +++++ src/components/DeployPage.js | 20 ++++++++++---------- 6 files changed, 54 insertions(+), 54 deletions(-) delete mode 100644 contracts/SusuBizLogic.sol create mode 100644 contracts/SusuParent.sol delete mode 100644 migrations/3_deploy_susu.js create mode 100644 migrations/3_deploy_susu_parent.js diff --git a/contracts/Susu.sol b/contracts/Susu.sol index 3305546..c80e44c 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -1,28 +1,22 @@ pragma solidity ^0.4.22; -import "./SusuBizLogic.sol"; +import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; +import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; import "./SusuDataStore.sol"; -contract Susu { +contract Susu is Ownable { - mapping(bytes32 => address) public deployedSusus; - string public foo = "bar"; + SusuDataStore public susuDataStore; + uint8 constant public MAX_MEMBERS = 5; - function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public returns(address) { - SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); - SusuBizLogic susu = new SusuBizLogic(susuDataStore); - deployedSusus[_key] = susu; - return susu; + constructor(address _susuDataStoreAddress) public { + susuDataStore = SusuDataStore(_susuDataStoreAddress); + require(susuDataStore.groupSize() <= MAX_MEMBERS); + susuDataStore.addMember(owner); } - function getSusu(bytes32 _key) public constant returns(address) { - return deployedSusus[_key]; - } - - function getGroupName(bytes32 _key) public view returns(string) { - address susuAddress = deployedSusus[_key]; - SusuBizLogic susu = SusuBizLogic(susuAddress); - return susu.getGroupName(); + function getGroupName() public view returns(string) { + return susuDataStore.getGroupName(); } } diff --git a/contracts/SusuBizLogic.sol b/contracts/SusuBizLogic.sol deleted file mode 100644 index 69e6956..0000000 --- a/contracts/SusuBizLogic.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.22; - -import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; -import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; -import "./SusuDataStore.sol"; - -contract SusuBizLogic is Ownable { - - SusuDataStore public susuDataStore; - uint8 constant public MAX_MEMBERS = 5; - - constructor(address _susuDataStoreAddress) public { - susuDataStore = SusuDataStore(_susuDataStoreAddress); - require(susuDataStore.groupSize() <= MAX_MEMBERS); - susuDataStore.addMember(owner); - } - - function getGroupName() public view returns(string) { - return susuDataStore.getGroupName(); - } - -} diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol new file mode 100644 index 0000000..70044a9 --- /dev/null +++ b/contracts/SusuParent.sol @@ -0,0 +1,28 @@ +pragma solidity ^0.4.22; + +import "./Susu.sol"; +import "./SusuDataStore.sol"; + +contract SusuParent { + + mapping(bytes32 => address) public deployedSusus; + string public foo = "bar"; + + function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public returns(address) { + SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); + Susu susu = new Susu(susuDataStore); + deployedSusus[_key] = susu; + return susu; + } + + function getSusu(bytes32 _key) public constant returns(address) { + return deployedSusus[_key]; + } + + function getGroupName(bytes32 _key) public view returns(string) { + address susuAddress = deployedSusus[_key]; + Susu susu = Susu(susuAddress); + return susu.getGroupName(); + } + +} diff --git a/migrations/3_deploy_susu.js b/migrations/3_deploy_susu.js deleted file mode 100644 index da1f00f..0000000 --- a/migrations/3_deploy_susu.js +++ /dev/null @@ -1,5 +0,0 @@ -var Susu = artifacts.require("./Susu.sol"); - -module.exports = function (deployer) { - deployer.deploy(Susu); -}; diff --git a/migrations/3_deploy_susu_parent.js b/migrations/3_deploy_susu_parent.js new file mode 100644 index 0000000..7f90965 --- /dev/null +++ b/migrations/3_deploy_susu_parent.js @@ -0,0 +1,5 @@ +var SusuParent = artifacts.require("./SusuParent.sol"); + +module.exports = function (deployer) { + deployer.deploy(SusuParent); +}; diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index 329c218..23ce824 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -1,11 +1,11 @@ import React, { Component } from 'react' import contract from 'truffle-contract' -import SusuOrigContract from '../../build/contracts/SusuOrig.json' +import SusuContract from '../../build/contracts/SusuOrig.json' import getWeb3 from '../utils/getWeb3' import '../App.css' -import SusuContract from "../../build/contracts/Susu"; +import SusuParentContract from "../../build/contracts/SusuParent"; class DeployPage extends Component { @@ -15,7 +15,7 @@ class DeployPage extends Component { this.state = { web3: null, isLoading: false, - susuContract: null, + susuParentContract: null, } } @@ -35,10 +35,10 @@ class DeployPage extends Component { instantiateSusuContract() { const contract = require("truffle-contract"); - const susuContract = contract(SusuContract); + const susuParentContract = contract(SusuParentContract); const provider = new this.state.web3.providers.HttpProvider("http://127.0.0.1:7545"); - susuContract.setProvider(provider); - this.setState({susuContract: susuContract}); + susuParentContract.setProvider(provider); + this.setState({susuParentContract: susuParentContract}); } render() { @@ -81,7 +81,7 @@ class DeployPage extends Component { createSusu(e) { e.preventDefault(); - this.state.susuContract.deployed().then((instance)=>{ + this.state.susuParentContract.deployed().then((instance)=>{ const options = { from: this.state.web3.eth.accounts[0], gas: 1000000 } return instance.createSusu('key1', 2, 'name', 1, options); }).then((result)=>{console.log('result:',result);}); @@ -89,14 +89,14 @@ class DeployPage extends Component { getSusu(e) { e.preventDefault(); - this.state.susuContract.deployed().then((instance)=>{ + this.state.susuParentContract.deployed().then((instance)=>{ return instance.getSusu.call('key1'); }).then((result)=>{console.log('result:',result);}); } getSusuName(e) { e.preventDefault(); - this.state.susuContract.deployed().then((instance)=>{ + this.state.susuParentContract.deployed().then((instance)=>{ return instance.getGroupName.call('key1'); }).then((result)=>{console.log('result:',result);}); } @@ -104,7 +104,7 @@ class DeployPage extends Component { clickCreate(e) { e.preventDefault(); this.setState({isLoading:true}); - const susuContract = contract(SusuOrigContract); + const susuContract = contract(SusuContract); const { unlinked_binary, abi } = susuContract; const newContract = this.state.web3.eth.contract(abi) const options = { from: this.state.web3.eth.accounts[0], data: unlinked_binary, gas: 2000000 } From 03511d69365077c9607a2512d1e00d50f6b917f1 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Wed, 15 Aug 2018 09:23:08 -0700 Subject: [PATCH 14/33] Get data from Susu biz logic contract (not from parent) --- contracts/SusuParent.sol | 9 +-------- src/components/DeployPage.js | 28 ++++++++++++++++++++-------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index 70044a9..32b9a49 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -8,21 +8,14 @@ contract SusuParent { mapping(bytes32 => address) public deployedSusus; string public foo = "bar"; - function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public returns(address) { + function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); Susu susu = new Susu(susuDataStore); deployedSusus[_key] = susu; - return susu; } function getSusu(bytes32 _key) public constant returns(address) { return deployedSusus[_key]; } - function getGroupName(bytes32 _key) public view returns(string) { - address susuAddress = deployedSusus[_key]; - Susu susu = Susu(susuAddress); - return susu.getGroupName(); - } - } diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index 23ce824..bbde88e 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -1,11 +1,12 @@ import React, { Component } from 'react' import contract from 'truffle-contract' -import SusuContract from '../../build/contracts/SusuOrig.json' import getWeb3 from '../utils/getWeb3' import '../App.css' import SusuParentContract from "../../build/contracts/SusuParent"; +import SusuOrigContract from "../../build/contracts/SusuOrig"; +import SusuContract from "../../build/contracts/Susu"; class DeployPage extends Component { @@ -16,6 +17,8 @@ class DeployPage extends Component { web3: null, isLoading: false, susuParentContract: null, + susuContract: null, + key:'', } } @@ -82,29 +85,38 @@ class DeployPage extends Component { createSusu(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ + const milliseconds = (new Date()).getTime(); + const key = 'key_'+milliseconds; + const name = 'name_'+milliseconds; + console.log('key:',key); + this.setState({key: key}); const options = { from: this.state.web3.eth.accounts[0], gas: 1000000 } - return instance.createSusu('key1', 2, 'name', 1, options); + return instance.createSusu(key, 2, name, 1, options); }).then((result)=>{console.log('result:',result);}); } getSusu(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ - return instance.getSusu.call('key1'); - }).then((result)=>{console.log('result:',result);}); + return instance.getSusu.call(this.state.key); + }).then((susuContract)=>{ + console.log('susuContract:',susuContract); + this.setState({susuContract: susuContract}); + }); } getSusuName(e) { e.preventDefault(); - this.state.susuParentContract.deployed().then((instance)=>{ - return instance.getGroupName.call('key1'); - }).then((result)=>{console.log('result:',result);}); + const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(this.state.susuContract); + susuContract.getGroupName((err, groupName)=>{ + console.log('err:',err, ' groupName:', groupName); + }); } clickCreate(e) { e.preventDefault(); this.setState({isLoading:true}); - const susuContract = contract(SusuContract); + const susuContract = contract(SusuOrigContract); const { unlinked_binary, abi } = susuContract; const newContract = this.state.web3.eth.contract(abi) const options = { from: this.state.web3.eth.accounts[0], data: unlinked_binary, gas: 2000000 } From b78e07b24b33782ce7836ed98f0948fd9e54cee4 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Wed, 15 Aug 2018 10:13:31 -0700 Subject: [PATCH 15/33] getManyMembers --- contracts/Susu.sol | 76 ++++++++++++++++++++++++++++++++++++ contracts/SusuDataStore.sol | 12 +++++- src/components/DeployPage.js | 19 +++++++-- 3 files changed, 101 insertions(+), 6 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index c80e44c..7eff3e6 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -19,4 +19,80 @@ contract Susu is Ownable { return susuDataStore.getGroupName(); } + +// function pullPayOut() public payable { +// require(msg.sender == members[memberIdxToPayNext]); +// resetBalances(); +// iterateMemberToPayNext(); +// msg.sender.transfer(members.length * contribAmtWei); +// } +// +// function everyonePaid() private view returns (bool) { +// for (uint i = 0; i < members.length ; i++) +// { +// if(currentContributions[members[i]] != contribAmtWei) +// return false; +// } +// return true; +// } +// +// function resetBalances() private { +// for (uint i = 0; i < members.length ; i++) +// { +// currentContributions[members[i]] = 0; +// } +// } +// +// function iterateMemberToPayNext() private { +// for (uint i = 0; i < members.length ; i++) +// { +// if(members[i] == members[memberIdxToPayNext]) { +// if(i < members.length - 1) { +// memberIdxToPayNext = i.add(1); +// return; +// } +// +// memberIdxToPayNext = 0; +// return; +// } +// } +// } +// +// function getMemberAtIndex(uint8 index) public view returns(address) { +// return members[index]; +// } +// +// function getContributionForMember(address _member) public view returns(uint256) { +// return currentContributions[_member]; +// } +// +// function amIOwner() public view returns(bool) { +// return (msg.sender == owner); +// } + + function getManyMembers() public view returns(uint) { + return susuDataStore.getManyMembers(); + } +// +// function joinGroup() public { +// require(!isRecipient(msg.sender)); +// members.push(msg.sender); +// } +// +// function isRecipient(address addr) private view returns (bool) { +// for (uint i = 0; i < members.length ; i++) +// { +// if(members[i] == addr) +// return true; +// } +// return false; +// } +// +// function () external payable { +// require(msg.value == contribAmtWei); +// require(isRecipient(msg.sender)); +// require(currentContributions[msg.sender] == 0); +// currentContributions[msg.sender] = msg.value; +// } + } diff --git a/contracts/SusuDataStore.sol b/contracts/SusuDataStore.sol index d2f121b..28a8b8d 100644 --- a/contracts/SusuDataStore.sol +++ b/contracts/SusuDataStore.sol @@ -14,12 +14,20 @@ contract SusuDataStore { groupSize = _groupSize; } + function getGroupName() public view returns(string) { + return groupName; + } + function addMember(address _member) public returns(address[]){ members.push(_member); } - function getGroupName() public view returns(string) { - return groupName; + function getManyMembers() public view returns(uint) { + return members.length; + } + + function getMemberAtIndex(uint8 index) public view returns(address) { + return members[index]; } } diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index bbde88e..892dc36 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -7,6 +7,7 @@ import '../App.css' import SusuParentContract from "../../build/contracts/SusuParent"; import SusuOrigContract from "../../build/contracts/SusuOrig"; import SusuContract from "../../build/contracts/Susu"; +import {BigNumber} from "bignumber.js"; class DeployPage extends Component { @@ -54,6 +55,7 @@ class DeployPage extends Component { +
@@ -99,20 +101,29 @@ class DeployPage extends Component { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ return instance.getSusu.call(this.state.key); - }).then((susuContract)=>{ - console.log('susuContract:',susuContract); + }).then((susuContractAddress)=>{ + console.log('susuContractAddress:',susuContractAddress); + const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); this.setState({susuContract: susuContract}); }); } getSusuName(e) { e.preventDefault(); - const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(this.state.susuContract); - susuContract.getGroupName((err, groupName)=>{ + this.state.susuContract.getGroupName((err, groupName)=>{ console.log('err:',err, ' groupName:', groupName); }); } + getManyMembers(e) { + e.preventDefault(); + this.state.susuContract.getManyMembers((err, getManyMembersBig)=>{ + let bigNumber = new BigNumber(getManyMembersBig); + const getManyMembers = bigNumber.toNumber(); + console.log('err:',err, ' getManyMembers:', getManyMembers); + }); + } + clickCreate(e) { e.preventDefault(); this.setState({isLoading:true}); From 52c41339b2a24e9666fa13ee48679f7861d4825f Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Wed, 15 Aug 2018 10:22:58 -0700 Subject: [PATCH 16/33] Rename groupName, getMemberAtIndex, amIOwner --- contracts/Susu.sol | 22 +++++++++++----------- contracts/SusuDataStore.sol | 8 ++------ src/components/DeployPage.js | 36 ++++++++++++++++++++++++++++++------ 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index 7eff3e6..d47802f 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -15,8 +15,8 @@ contract Susu is Ownable { susuDataStore.addMember(owner); } - function getGroupName() public view returns(string) { - return susuDataStore.getGroupName(); + function groupName() public view returns(string) { + return susuDataStore.groupName(); } @@ -57,18 +57,18 @@ contract Susu is Ownable { // } // } // } -// -// function getMemberAtIndex(uint8 index) public view returns(address) { -// return members[index]; -// } -// + + function getMemberAtIndex(uint8 _index) public view returns(address) { + return susuDataStore.getMemberAtIndex(_index); + } + // function getContributionForMember(address _member) public view returns(uint256) { // return currentContributions[_member]; // } -// -// function amIOwner() public view returns(bool) { -// return (msg.sender == owner); -// } + + function amIOwner() public view returns(bool) { + return (msg.sender == owner); + } function getManyMembers() public view returns(uint) { return susuDataStore.getManyMembers(); diff --git a/contracts/SusuDataStore.sol b/contracts/SusuDataStore.sol index 28a8b8d..b90ef8e 100644 --- a/contracts/SusuDataStore.sol +++ b/contracts/SusuDataStore.sol @@ -14,10 +14,6 @@ contract SusuDataStore { groupSize = _groupSize; } - function getGroupName() public view returns(string) { - return groupName; - } - function addMember(address _member) public returns(address[]){ members.push(_member); } @@ -26,8 +22,8 @@ contract SusuDataStore { return members.length; } - function getMemberAtIndex(uint8 index) public view returns(address) { - return members[index]; + function getMemberAtIndex(uint8 _index) public view returns(address) { + return members[_index]; } } diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index 892dc36..624ecf7 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -53,9 +53,12 @@ class DeployPage extends Component {
- - + + + + +
@@ -92,12 +95,12 @@ class DeployPage extends Component { const name = 'name_'+milliseconds; console.log('key:',key); this.setState({key: key}); - const options = { from: this.state.web3.eth.accounts[0], gas: 1000000 } + const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 } return instance.createSusu(key, 2, name, 1, options); }).then((result)=>{console.log('result:',result);}); } - getSusu(e) { + setSusu(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ return instance.getSusu.call(this.state.key); @@ -108,9 +111,9 @@ class DeployPage extends Component { }); } - getSusuName(e) { + groupName(e) { e.preventDefault(); - this.state.susuContract.getGroupName((err, groupName)=>{ + this.state.susuContract.groupName((err, groupName)=>{ console.log('err:',err, ' groupName:', groupName); }); } @@ -124,6 +127,27 @@ class DeployPage extends Component { }); } + getMemberAtIndex0(e) { + e.preventDefault(); + this.state.susuContract.getMemberAtIndex(0, (err, memberAddress)=>{ + console.log('err:',err, ' memberAddress0:', memberAddress); + }); + } + + getMemberAtIndex1(e) { + e.preventDefault(); + this.state.susuContract.getMemberAtIndex(1, (err, memberAddress)=>{ + console.log('err:',err, ' memberAddress1:', memberAddress); + }); + } + + amIOwner(e) { + e.preventDefault(); + this.state.susuContract.amIOwner((err, amIOwner)=>{ + console.log('err:',err, ' amIOwner:', amIOwner); + }); + } + clickCreate(e) { e.preventDefault(); this.setState({isLoading:true}); From c4c3917408af2bea7a889b26cddad52a3cea35f4 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Wed, 15 Aug 2018 10:27:39 -0700 Subject: [PATCH 17/33] fix ownership --- contracts/Susu.sol | 4 ++-- contracts/SusuParent.sol | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index d47802f..f23507f 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -9,10 +9,10 @@ contract Susu is Ownable { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - constructor(address _susuDataStoreAddress) public { + constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); require(susuDataStore.groupSize() <= MAX_MEMBERS); - susuDataStore.addMember(owner); + susuDataStore.addMember(_newOwner); } function groupName() public view returns(string) { diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index 32b9a49..d12a32e 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -10,8 +10,9 @@ contract SusuParent { function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); - Susu susu = new Susu(susuDataStore); + Susu susu = new Susu(susuDataStore, msg.sender); deployedSusus[_key] = susu; + susu.transferOwnership(msg.sender); } function getSusu(bytes32 _key) public constant returns(address) { From d964510f2551e81b445c645b7b96943c2457f0a2 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Wed, 15 Aug 2018 14:57:27 -0700 Subject: [PATCH 18/33] trying to figure out why 'owner' doesn't always work. i think i have to send the from option --- contracts/Susu.sol | 31 +++++++++++++------------- contracts/SusuParent.sol | 11 ++++----- src/components/DeployPage.js | 43 ++++++++++++++++++++++++++---------- 3 files changed, 53 insertions(+), 32 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index f23507f..dedb548 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -73,21 +73,22 @@ contract Susu is Ownable { function getManyMembers() public view returns(uint) { return susuDataStore.getManyMembers(); } -// -// function joinGroup() public { -// require(!isRecipient(msg.sender)); -// members.push(msg.sender); -// } -// -// function isRecipient(address addr) private view returns (bool) { -// for (uint i = 0; i < members.length ; i++) -// { -// if(members[i] == addr) -// return true; -// } -// return false; -// } -// + + function joinGroup() public { + require(!isRecipient(msg.sender)); + susuDataStore.addMember(msg.sender); + } + + function isRecipient(address addr) private view returns (bool) { + uint manyMembers = getManyMembers(); + for (uint8 i = 0; i < manyMembers ; i++) + { + if(getMemberAtIndex(i) == addr) + return true; + } + return false; + } + // function () external payable { // require(msg.value == contribAmtWei); // require(isRecipient(msg.sender)); diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index d12a32e..38e750e 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -6,13 +6,14 @@ import "./SusuDataStore.sol"; contract SusuParent { mapping(bytes32 => address) public deployedSusus; - string public foo = "bar"; function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { - SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); - Susu susu = new Susu(susuDataStore, msg.sender); - deployedSusus[_key] = susu; - susu.transferOwnership(msg.sender); + if(deployedSusus[_key] == 0x0){ + SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); + Susu susu = new Susu(susuDataStore, msg.sender); + deployedSusus[_key] = susu; + susu.transferOwnership(msg.sender); + } } function getSusu(bytes32 _key) public constant returns(address) { diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index 624ecf7..c3a1fe6 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -19,7 +19,7 @@ class DeployPage extends Component { isLoading: false, susuParentContract: null, susuContract: null, - key:'', + key:'key_xxx', } } @@ -43,6 +43,8 @@ class DeployPage extends Component { const provider = new this.state.web3.providers.HttpProvider("http://127.0.0.1:7545"); susuParentContract.setProvider(provider); this.setState({susuParentContract: susuParentContract}); + + console.log('accounts:',this.state.web3.eth.accounts); } render() { @@ -58,7 +60,9 @@ class DeployPage extends Component { + +
@@ -90,13 +94,13 @@ class DeployPage extends Component { createSusu(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ - const milliseconds = (new Date()).getTime(); - const key = 'key_'+milliseconds; - const name = 'name_'+milliseconds; - console.log('key:',key); - this.setState({key: key}); - const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 } - return instance.createSusu(key, 2, name, 1, options); + // const milliseconds = (new Date()).getTime(); + // const key = 'key_'+milliseconds; + // const name = 'name_'+milliseconds; + // console.log('key:',key); + // this.setState({key: key}); + const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; + return instance.createSusu(this.state.key, 2, name, 1, options); }).then((result)=>{console.log('result:',result);}); } @@ -141,26 +145,41 @@ class DeployPage extends Component { }); } + owner(e) { + e.preventDefault(); + const options = {from: this.state.web3.eth.accounts[0]}; + this.state.susuContract.owner(options, (err, owner)=>{ + console.log('err:',err, ' owner:', owner, ' =?me', (owner===this.state.web3.eth.accounts[0])); + }); + } + amIOwner(e) { e.preventDefault(); - this.state.susuContract.amIOwner((err, amIOwner)=>{ + const options = {from: this.state.web3.eth.accounts[0]}; + this.state.susuContract.amIOwner(options, (err, amIOwner)=>{ console.log('err:',err, ' amIOwner:', amIOwner); }); } + joinGroup(e) { + e.preventDefault(); + const options = {from: this.state.web3.eth.accounts[0], gas: 2000000}; + this.state.susuContract.joinGroup(options, (err, resp)=>{console.log('err:',err, ' resp:', resp);}); + } + clickCreate(e) { e.preventDefault(); this.setState({isLoading:true}); const susuContract = contract(SusuOrigContract); const { unlinked_binary, abi } = susuContract; - const newContract = this.state.web3.eth.contract(abi) - const options = { from: this.state.web3.eth.accounts[0], data: unlinked_binary, gas: 2000000 } + const newContract = this.state.web3.eth.contract(abi); + const options = { from: this.state.web3.eth.accounts[0], data: unlinked_binary, gas: 2000000 }; const groupSize = document.getElementById('group_size').value; const groupName = document.getElementById('group_name').value; const contribAmtEth = document.getElementById('contrib_amt').value; const contribAmtWei = this.state.web3.toWei(contribAmtEth, 'ether'); - newContract.new(groupSize, groupName, contribAmtWei, options, this.newContractCallback()) + newContract.new(groupSize, groupName, contribAmtWei, options, this.newContractCallback()); } newContractCallback() { From ec24f11e4fe0ae80fc1118069c0c9ce2fb6c56f1 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Wed, 15 Aug 2018 15:16:01 -0700 Subject: [PATCH 19/33] getContributionForMember --- contracts/Susu.sol | 6 +++--- contracts/SusuDataStore.sol | 4 ++++ src/components/DeployPage.js | 10 ++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index dedb548..f1c849b 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -62,9 +62,9 @@ contract Susu is Ownable { return susuDataStore.getMemberAtIndex(_index); } -// function getContributionForMember(address _member) public view returns(uint256) { -// return currentContributions[_member]; -// } + function getContributionForMember(address _member) public view returns(uint256) { + return susuDataStore.getContributionForMember(_member); + } function amIOwner() public view returns(bool) { return (msg.sender == owner); diff --git a/contracts/SusuDataStore.sol b/contracts/SusuDataStore.sol index b90ef8e..05fd3dc 100644 --- a/contracts/SusuDataStore.sol +++ b/contracts/SusuDataStore.sol @@ -26,4 +26,8 @@ contract SusuDataStore { return members[_index]; } + function getContributionForMember(address _member) public view returns(uint256) { + return currentContributions[_member]; + } + } diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index c3a1fe6..82bc260 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -63,6 +63,7 @@ class DeployPage extends Component { +
@@ -131,6 +132,15 @@ class DeployPage extends Component { }); } + getContributionForMember(e) { + e.preventDefault(); + this.state.susuContract.getContributionForMember(this.state.web3.eth.accounts[0], (err, getContributionForMemberBig)=>{ + let bigNumber = new BigNumber(getContributionForMemberBig); + const getContributionForMember = bigNumber.toNumber(); + console.log('err:',err, ' getContributionForMember:', getContributionForMember); + }); + } + getMemberAtIndex0(e) { e.preventDefault(); this.state.susuContract.getMemberAtIndex(0, (err, memberAddress)=>{ From 6e85e02a83fbd15cdf0b6e8b1b1facbe2ccc7365 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Wed, 15 Aug 2018 17:13:20 -0700 Subject: [PATCH 20/33] Init upgrade methods --- contracts/Susu.sol | 11 +++++++++++ contracts/SusuParent.sol | 16 ++++++++++++++++ src/components/DeployPage.js | 27 ++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index f1c849b..cf11e30 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -8,6 +8,7 @@ contract Susu is Ownable { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; + string public version = '0.0.1'; constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); @@ -19,6 +20,9 @@ contract Susu is Ownable { return susuDataStore.groupName(); } + function foo() public pure returns(string) { + return 'bar_0.0.1'; + } // function pullPayOut() public payable { // require(msg.sender == members[memberIdxToPayNext]); @@ -96,4 +100,11 @@ contract Susu is Ownable { // currentContributions[msg.sender] = msg.value; // } + // onlyOwner? + function kill() public pure { +// ???=> var tokenBalance = susuDataStore.balanceOf(this); +// ???=> tokenLedger.transfer(_upgradedSusu, tokenBalance); +// ???=> selfdestruct(_upgradedSusu); + } + } diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index 38e750e..03ccbf8 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -1,12 +1,15 @@ pragma solidity ^0.4.22; +import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; import "./Susu.sol"; import "./SusuDataStore.sol"; +// is Ownable ? contract SusuParent { mapping(bytes32 => address) public deployedSusus; + // onlyOwner? function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { if(deployedSusus[_key] == 0x0){ SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); @@ -20,4 +23,17 @@ contract SusuParent { return deployedSusus[_key]; } + // onlyOwner? + function upgradeSusu(bytes32 _key) public { + address susuAddress = deployedSusus[_key]; + Susu susu = Susu(susuAddress); + SusuDataStore susuDataStore = susu.susuDataStore(); + + Susu susuNew = new Susu(susuDataStore, susu.owner()); + + susu.kill(); + + deployedSusus[_key] = susuNew; + } + } diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index 82bc260..b0295d3 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -64,6 +64,9 @@ class DeployPage extends Component { + + +
@@ -102,7 +105,15 @@ class DeployPage extends Component { // this.setState({key: key}); const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; return instance.createSusu(this.state.key, 2, name, 1, options); - }).then((result)=>{console.log('result:',result);}); + }).then((result)=>{console.log('createSusu result:',result);}); + } + + upgradeSusu(e) { + e.preventDefault(); + this.state.susuParentContract.deployed().then((instance)=>{ + const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; + return instance.upgradeSusu(this.state.key, options); + }).then((result)=>{console.log('upgradeSusu result:',result);}); } setSusu(e) { @@ -116,6 +127,20 @@ class DeployPage extends Component { }); } + foo(e) { + e.preventDefault(); + this.state.susuContract.foo((err, foo)=>{ + console.log('err:',err, ' foo:', foo); + }); + } + + version(e) { + e.preventDefault(); + this.state.susuContract.version((err, version)=>{ + console.log('err:',err, ' version:', version); + }); + } + groupName(e) { e.preventDefault(); this.state.susuContract.groupName((err, groupName)=>{ From c3c9bbb627156669ea9aea5501f3104aea3680e4 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Thu, 16 Aug 2018 14:08:40 -0700 Subject: [PATCH 21/33] solidity init updates for registry. IRegistry, susuRegistry --- contracts/IRegistry.sol | 6 +++ contracts/Susu.sol | 2 +- contracts/SusuParent.sol | 40 +++++++++++-------- contracts/SusuRegistry.sol | 16 ++++++++ migrations/3_deploy_susu_parent.js | 11 ++++- src/components/DeployPage.js | 64 ++++++++++++++++++++---------- 6 files changed, 98 insertions(+), 41 deletions(-) create mode 100644 contracts/IRegistry.sol create mode 100644 contracts/SusuRegistry.sol diff --git a/contracts/IRegistry.sol b/contracts/IRegistry.sol new file mode 100644 index 0000000..24d9544 --- /dev/null +++ b/contracts/IRegistry.sol @@ -0,0 +1,6 @@ +pragma solidity ^0.4.22; + +interface IRegistry { + function put(bytes32 _key, address _contractAddress) external; + function get(bytes32 _key) external returns(address); +} diff --git a/contracts/Susu.sol b/contracts/Susu.sol index cf11e30..a271790 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -8,7 +8,7 @@ contract Susu is Ownable { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - string public version = '0.0.1'; + string public version = '0.0.2'; constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index 03ccbf8..d72cd24 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -3,37 +3,43 @@ pragma solidity ^0.4.22; import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; import "./Susu.sol"; import "./SusuDataStore.sol"; +import "./IRegistry.sol"; // is Ownable ? contract SusuParent { - mapping(bytes32 => address) public deployedSusus; + IRegistry public registry; + + constructor(address _registry) public { + registry = IRegistry(_registry); + } // onlyOwner? - function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) public { - if(deployedSusus[_key] == 0x0){ + function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) external { + address susuOrigAddress = register.get(_key); + if(susuOrigAddress == 0x0){ SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); Susu susu = new Susu(susuDataStore, msg.sender); - deployedSusus[_key] = susu; + register.put(_key, susu); susu.transferOwnership(msg.sender); } } - function getSusu(bytes32 _key) public constant returns(address) { - return deployedSusus[_key]; + function getSusu(bytes32 _key) external constant returns(address) { + return register.get(_key); } // onlyOwner? - function upgradeSusu(bytes32 _key) public { - address susuAddress = deployedSusus[_key]; - Susu susu = Susu(susuAddress); - SusuDataStore susuDataStore = susu.susuDataStore(); - - Susu susuNew = new Susu(susuDataStore, susu.owner()); - - susu.kill(); - - deployedSusus[_key] = susuNew; - } +// function upgradeSusu(bytes32 _key) external { +// address susuAddress = deployedSusus[_key]; +// Susu susu = Susu(susuAddress); +// SusuDataStore susuDataStore = susu.susuDataStore(); +// +// Susu susuNew = new Susu(susuDataStore, susu.owner()); +// +// susu.kill(); +// +// deployedSusus[_key] = susuNew; +// } } diff --git a/contracts/SusuRegistry.sol b/contracts/SusuRegistry.sol new file mode 100644 index 0000000..997165f --- /dev/null +++ b/contracts/SusuRegistry.sol @@ -0,0 +1,16 @@ +pragma solidity ^0.4.22; + +import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; +import "./IRegistry.sol"; + +contract SusuRegistry is IRegistry, Ownable { + mapping(bytes32 => address) public registry; + + function put(bytes32 _key, address _contractAddress) external onlyOwner { + registry[_key] = _contractAddress; + } + + function get(bytes32 _key) external returns(address){ + return registry[_key]; + } +} \ No newline at end of file diff --git a/migrations/3_deploy_susu_parent.js b/migrations/3_deploy_susu_parent.js index 7f90965..b0eca7d 100644 --- a/migrations/3_deploy_susu_parent.js +++ b/migrations/3_deploy_susu_parent.js @@ -1,5 +1,12 @@ -var SusuParent = artifacts.require("./SusuParent.sol"); +var SusuParent = artifacts.require("SusuParent"); +var SusuRegister = artifacts.require("SusuRegister"); module.exports = function (deployer) { - deployer.deploy(SusuParent); + deployer.deploy(SusuParent).then((SusuParentContract)=>{ + console.log('SusuParentContract.address:',SusuParentContract.address); + deployer.deploy(SusuRegister, 'bar').then((SusuRegisterContract)=>{ + SusuRegisterContract.foo().then(foo=>{console.log('SusuRegisterContract.foo:',foo)}); + SusuRegister.deployed().then(instance=>{instance.foo().then(foo=>{console.log('instance.foo:',foo)})}); + }); + }); }; diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index b0295d3..3c0b3e5 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -19,6 +19,7 @@ class DeployPage extends Component { isLoading: false, susuParentContract: null, susuContract: null, + susuContract_old: null, key:'key_xxx', } } @@ -54,19 +55,23 @@ class DeployPage extends Component {
- - - - - - - - - - - - - + + + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/}
@@ -98,11 +103,14 @@ class DeployPage extends Component { createSusu(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ - // const milliseconds = (new Date()).getTime(); - // const key = 'key_'+milliseconds; - // const name = 'name_'+milliseconds; - // console.log('key:',key); - // this.setState({key: key}); + const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; + return instance.createSusu(this.state.key, 2, name, 1, options); + }).then((result)=>{console.log('createSusu result:',result);}); + } + + upgradeToLatestSusu(e) { + e.preventDefault(); + this.state.susuParentContract.deployed().then((instance)=>{ const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; return instance.createSusu(this.state.key, 2, name, 1, options); }).then((result)=>{console.log('createSusu result:',result);}); @@ -127,6 +135,13 @@ class DeployPage extends Component { }); } + setSusu_old(e) { + e.preventDefault(); + console.log('susuContractAddress_old:','0xf077a4cc347b823759cfc37189f7dc365858d787'); + const susuContract_old = this.state.web3.eth.contract(SusuContract.abi).at('0xf077a4cc347b823759cfc37189f7dc365858d787'); + this.setState({susuContract_old: susuContract_old}); + } + foo(e) { e.preventDefault(); this.state.susuContract.foo((err, foo)=>{ @@ -134,10 +149,17 @@ class DeployPage extends Component { }); } - version(e) { + version_old(e) { + e.preventDefault(); + this.state.susuContract_old.version((err, version_old)=>{ + console.log('err:',err, ' version_old:', version_old); + }); + } + + version_new(e) { e.preventDefault(); - this.state.susuContract.version((err, version)=>{ - console.log('err:',err, ' version:', version); + this.state.susuContract.version((err, version_new)=>{ + console.log('err:',err, ' version_new:', version_new); }); } From fc29f558c317ca386b9e2ba65a8f78c96ee949c5 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Thu, 16 Aug 2018 14:28:40 -0700 Subject: [PATCH 22/33] cleanup --- contracts/IRegistry.sol | 2 +- contracts/SusuParent.sol | 8 ++++---- contracts/SusuRegistry.sol | 2 +- migrations/1_initial_migration.js | 2 +- migrations/3_deploy_susu_parent.js | 12 ------------ migrations/3_deploy_susu_registry.js | 5 +++++ migrations/4_deploy_susu_parent.js | 6 ++++++ 7 files changed, 18 insertions(+), 19 deletions(-) delete mode 100644 migrations/3_deploy_susu_parent.js create mode 100644 migrations/3_deploy_susu_registry.js create mode 100644 migrations/4_deploy_susu_parent.js diff --git a/contracts/IRegistry.sol b/contracts/IRegistry.sol index 24d9544..d516acc 100644 --- a/contracts/IRegistry.sol +++ b/contracts/IRegistry.sol @@ -2,5 +2,5 @@ pragma solidity ^0.4.22; interface IRegistry { function put(bytes32 _key, address _contractAddress) external; - function get(bytes32 _key) external returns(address); + function get(bytes32 _key) view external returns(address); } diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index d72cd24..7f50a6e 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -16,17 +16,17 @@ contract SusuParent { // onlyOwner? function createSusu(bytes32 _key, uint8 _groupSize, string _groupName, uint256 _contribAmtWei) external { - address susuOrigAddress = register.get(_key); + address susuOrigAddress = registry.get(_key); if(susuOrigAddress == 0x0){ SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); Susu susu = new Susu(susuDataStore, msg.sender); - register.put(_key, susu); + registry.put(_key, susu); susu.transferOwnership(msg.sender); } } - function getSusu(bytes32 _key) external constant returns(address) { - return register.get(_key); + function getSusu(bytes32 _key) view external returns(address) { + return registry.get(_key); } // onlyOwner? diff --git a/contracts/SusuRegistry.sol b/contracts/SusuRegistry.sol index 997165f..acc8a70 100644 --- a/contracts/SusuRegistry.sol +++ b/contracts/SusuRegistry.sol @@ -10,7 +10,7 @@ contract SusuRegistry is IRegistry, Ownable { registry[_key] = _contractAddress; } - function get(bytes32 _key) external returns(address){ + function get(bytes32 _key) view external returns(address){ return registry[_key]; } } \ No newline at end of file diff --git a/migrations/1_initial_migration.js b/migrations/1_initial_migration.js index 4d5f3f9..36a949b 100644 --- a/migrations/1_initial_migration.js +++ b/migrations/1_initial_migration.js @@ -1,4 +1,4 @@ -var Migrations = artifacts.require("./Migrations.sol"); +const Migrations = artifacts.require("./Migrations.sol"); module.exports = function(deployer) { deployer.deploy(Migrations); diff --git a/migrations/3_deploy_susu_parent.js b/migrations/3_deploy_susu_parent.js deleted file mode 100644 index b0eca7d..0000000 --- a/migrations/3_deploy_susu_parent.js +++ /dev/null @@ -1,12 +0,0 @@ -var SusuParent = artifacts.require("SusuParent"); -var SusuRegister = artifacts.require("SusuRegister"); - -module.exports = function (deployer) { - deployer.deploy(SusuParent).then((SusuParentContract)=>{ - console.log('SusuParentContract.address:',SusuParentContract.address); - deployer.deploy(SusuRegister, 'bar').then((SusuRegisterContract)=>{ - SusuRegisterContract.foo().then(foo=>{console.log('SusuRegisterContract.foo:',foo)}); - SusuRegister.deployed().then(instance=>{instance.foo().then(foo=>{console.log('instance.foo:',foo)})}); - }); - }); -}; diff --git a/migrations/3_deploy_susu_registry.js b/migrations/3_deploy_susu_registry.js new file mode 100644 index 0000000..1c2a928 --- /dev/null +++ b/migrations/3_deploy_susu_registry.js @@ -0,0 +1,5 @@ +const SusuRegistry = artifacts.require("SusuRegistry"); + +module.exports = function (deployer) { + deployer.deploy(SusuRegistry); +}; diff --git a/migrations/4_deploy_susu_parent.js b/migrations/4_deploy_susu_parent.js new file mode 100644 index 0000000..bf0541c --- /dev/null +++ b/migrations/4_deploy_susu_parent.js @@ -0,0 +1,6 @@ +const SusuParent = artifacts.require("SusuParent"); +const LATEST_REGISTRY_ADDRESS = 0x5301babd47c45593c88f944ff5a01bfdb577b5fb; + +module.exports = function (deployer) { + deployer.deploy(SusuParent, LATEST_REGISTRY_ADDRESS); +}; From 233e6ba3298086abdf6145e4a8ed8c93232b6c5b Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Thu, 16 Aug 2018 15:02:13 -0700 Subject: [PATCH 23/33] upgradeSusu and update DeployPage.js --- contracts/Susu.sol | 4 +- contracts/SusuParent.sol | 18 ++- migrations/4_deploy_susu_parent.js | 3 +- src/components/DeployPage.js | 184 ++++++++++++++--------------- 4 files changed, 103 insertions(+), 106 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index a271790..62d0f77 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -101,10 +101,10 @@ contract Susu is Ownable { // } // onlyOwner? - function kill() public pure { +// function kill() public pure { // ???=> var tokenBalance = susuDataStore.balanceOf(this); // ???=> tokenLedger.transfer(_upgradedSusu, tokenBalance); // ???=> selfdestruct(_upgradedSusu); - } +// } } diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index 7f50a6e..bad0dbc 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -30,16 +30,12 @@ contract SusuParent { } // onlyOwner? -// function upgradeSusu(bytes32 _key) external { -// address susuAddress = deployedSusus[_key]; -// Susu susu = Susu(susuAddress); -// SusuDataStore susuDataStore = susu.susuDataStore(); -// -// Susu susuNew = new Susu(susuDataStore, susu.owner()); -// -// susu.kill(); -// -// deployedSusus[_key] = susuNew; -// } + function upgradeSusu(bytes32 _key) external { + address susuAddressOrig = registry.get(_key); + Susu susu = Susu(susuAddressOrig); + Susu susuNew = new Susu(susu.susuDataStore(), susu.owner()); +// susu.kill(); // Transfer value? + registry.put(_key, susuNew); + } } diff --git a/migrations/4_deploy_susu_parent.js b/migrations/4_deploy_susu_parent.js index bf0541c..756f42e 100644 --- a/migrations/4_deploy_susu_parent.js +++ b/migrations/4_deploy_susu_parent.js @@ -1,5 +1,6 @@ const SusuParent = artifacts.require("SusuParent"); -const LATEST_REGISTRY_ADDRESS = 0x5301babd47c45593c88f944ff5a01bfdb577b5fb; +const SusuRegistry = artifacts.require("SusuRegistry"); +const LATEST_REGISTRY_ADDRESS = SusuRegistry.address; module.exports = function (deployer) { deployer.deploy(SusuParent, LATEST_REGISTRY_ADDRESS); diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index 3c0b3e5..e6cce0f 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -7,7 +7,7 @@ import '../App.css' import SusuParentContract from "../../build/contracts/SusuParent"; import SusuOrigContract from "../../build/contracts/SusuOrig"; import SusuContract from "../../build/contracts/Susu"; -import {BigNumber} from "bignumber.js"; +// import {BigNumber} from "bignumber.js"; class DeployPage extends Component { @@ -18,9 +18,9 @@ class DeployPage extends Component { web3: null, isLoading: false, susuParentContract: null, - susuContract: null, - susuContract_old: null, - key:'key_xxx', + susuContract1: null, + susuContract2: null, + key:'key', } } @@ -56,7 +56,11 @@ class DeployPage extends Component {
- + + + + + {/**/} {/**/} {/**/} @@ -108,121 +112,117 @@ class DeployPage extends Component { }).then((result)=>{console.log('createSusu result:',result);}); } - upgradeToLatestSusu(e) { + setSusu1(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ - const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; - return instance.createSusu(this.state.key, 2, name, 1, options); - }).then((result)=>{console.log('createSusu result:',result);}); + return instance.getSusu.call(this.state.key); + }).then((susuContractAddress)=>{ + console.log('susuContractAddress:',susuContractAddress); + const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); + this.setState({susuContract1: susuContract}); + }); } upgradeSusu(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; - return instance.upgradeSusu(this.state.key, options); - }).then((result)=>{console.log('upgradeSusu result:',result);}); + return instance.createSusu(this.state.key, 2, name, 1, options); + }).then((result)=>{console.log('createSusu result:',result);}); } - setSusu(e) { + setSusu2(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ return instance.getSusu.call(this.state.key); }).then((susuContractAddress)=>{ console.log('susuContractAddress:',susuContractAddress); const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); - this.setState({susuContract: susuContract}); - }); - } - - setSusu_old(e) { - e.preventDefault(); - console.log('susuContractAddress_old:','0xf077a4cc347b823759cfc37189f7dc365858d787'); - const susuContract_old = this.state.web3.eth.contract(SusuContract.abi).at('0xf077a4cc347b823759cfc37189f7dc365858d787'); - this.setState({susuContract_old: susuContract_old}); - } - - foo(e) { - e.preventDefault(); - this.state.susuContract.foo((err, foo)=>{ - console.log('err:',err, ' foo:', foo); - }); - } - - version_old(e) { - e.preventDefault(); - this.state.susuContract_old.version((err, version_old)=>{ - console.log('err:',err, ' version_old:', version_old); - }); - } - - version_new(e) { - e.preventDefault(); - this.state.susuContract.version((err, version_new)=>{ - console.log('err:',err, ' version_new:', version_new); - }); - } - - groupName(e) { - e.preventDefault(); - this.state.susuContract.groupName((err, groupName)=>{ - console.log('err:',err, ' groupName:', groupName); + this.setState({susuContract2: susuContract}); }); } - getManyMembers(e) { - e.preventDefault(); - this.state.susuContract.getManyMembers((err, getManyMembersBig)=>{ - let bigNumber = new BigNumber(getManyMembersBig); - const getManyMembers = bigNumber.toNumber(); - console.log('err:',err, ' getManyMembers:', getManyMembers); - }); - } + // foo(e) { + // e.preventDefault(); + // this.state.susuContract.foo((err, foo)=>{ + // console.log('err:',err, ' foo:', foo); + // }); + // } - getContributionForMember(e) { + version1(e) { e.preventDefault(); - this.state.susuContract.getContributionForMember(this.state.web3.eth.accounts[0], (err, getContributionForMemberBig)=>{ - let bigNumber = new BigNumber(getContributionForMemberBig); - const getContributionForMember = bigNumber.toNumber(); - console.log('err:',err, ' getContributionForMember:', getContributionForMember); + this.state.susuContract1.version((err, version1)=>{ + console.log('err:',err, ' version1:', version1); }); } - getMemberAtIndex0(e) { + version2(e) { e.preventDefault(); - this.state.susuContract.getMemberAtIndex(0, (err, memberAddress)=>{ - console.log('err:',err, ' memberAddress0:', memberAddress); + this.state.susuContract2.version((err, version2)=>{ + console.log('err:',err, ' version2:', version2); }); } - getMemberAtIndex1(e) { - e.preventDefault(); - this.state.susuContract.getMemberAtIndex(1, (err, memberAddress)=>{ - console.log('err:',err, ' memberAddress1:', memberAddress); - }); - } - - owner(e) { - e.preventDefault(); - const options = {from: this.state.web3.eth.accounts[0]}; - this.state.susuContract.owner(options, (err, owner)=>{ - console.log('err:',err, ' owner:', owner, ' =?me', (owner===this.state.web3.eth.accounts[0])); - }); - } - - amIOwner(e) { - e.preventDefault(); - const options = {from: this.state.web3.eth.accounts[0]}; - this.state.susuContract.amIOwner(options, (err, amIOwner)=>{ - console.log('err:',err, ' amIOwner:', amIOwner); - }); - } - - joinGroup(e) { - e.preventDefault(); - const options = {from: this.state.web3.eth.accounts[0], gas: 2000000}; - this.state.susuContract.joinGroup(options, (err, resp)=>{console.log('err:',err, ' resp:', resp);}); - } + // groupName(e) { + // e.preventDefault(); + // this.state.susuContract.groupName((err, groupName)=>{ + // console.log('err:',err, ' groupName:', groupName); + // }); + // } + // + // getManyMembers(e) { + // e.preventDefault(); + // this.state.susuContract.getManyMembers((err, getManyMembersBig)=>{ + // let bigNumber = new BigNumber(getManyMembersBig); + // const getManyMembers = bigNumber.toNumber(); + // console.log('err:',err, ' getManyMembers:', getManyMembers); + // }); + // } + // + // getContributionForMember(e) { + // e.preventDefault(); + // this.state.susuContract.getContributionForMember(this.state.web3.eth.accounts[0], (err, getContributionForMemberBig)=>{ + // let bigNumber = new BigNumber(getContributionForMemberBig); + // const getContributionForMember = bigNumber.toNumber(); + // console.log('err:',err, ' getContributionForMember:', getContributionForMember); + // }); + // } + // + // getMemberAtIndex0(e) { + // e.preventDefault(); + // this.state.susuContract.getMemberAtIndex(0, (err, memberAddress)=>{ + // console.log('err:',err, ' memberAddress0:', memberAddress); + // }); + // } + // + // getMemberAtIndex1(e) { + // e.preventDefault(); + // this.state.susuContract.getMemberAtIndex(1, (err, memberAddress)=>{ + // console.log('err:',err, ' memberAddress1:', memberAddress); + // }); + // } + // + // owner(e) { + // e.preventDefault(); + // const options = {from: this.state.web3.eth.accounts[0]}; + // this.state.susuContract.owner(options, (err, owner)=>{ + // console.log('err:',err, ' owner:', owner, ' =?me', (owner===this.state.web3.eth.accounts[0])); + // }); + // } + // + // amIOwner(e) { + // e.preventDefault(); + // const options = {from: this.state.web3.eth.accounts[0]}; + // this.state.susuContract.amIOwner(options, (err, amIOwner)=>{ + // console.log('err:',err, ' amIOwner:', amIOwner); + // }); + // } + // + // joinGroup(e) { + // e.preventDefault(); + // const options = {from: this.state.web3.eth.accounts[0], gas: 2000000}; + // this.state.susuContract.joinGroup(options, (err, resp)=>{console.log('err:',err, ' resp:', resp);}); + // } clickCreate(e) { e.preventDefault(); From 88faffb15ed4031a982e2df7ca715ee89fb18c26 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Thu, 16 Aug 2018 15:53:37 -0700 Subject: [PATCH 24/33] Remove Ownable --- contracts/Susu.sol | 18 ++++++++---------- contracts/SusuParent.sol | 6 +++--- contracts/SusuRegistry.sol | 8 +++++--- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index 62d0f77..e7134ab 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -1,14 +1,15 @@ pragma solidity ^0.4.22; -import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; -import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; +//import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; +//import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; import "./SusuDataStore.sol"; -contract Susu is Ownable { +// add Ownable +contract Susu { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - string public version = '0.0.2'; + string public version = '0.0.1'; constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); @@ -20,10 +21,6 @@ contract Susu is Ownable { return susuDataStore.groupName(); } - function foo() public pure returns(string) { - return 'bar_0.0.1'; - } - // function pullPayOut() public payable { // require(msg.sender == members[memberIdxToPayNext]); // resetBalances(); @@ -70,8 +67,9 @@ contract Susu is Ownable { return susuDataStore.getContributionForMember(_member); } - function amIOwner() public view returns(bool) { - return (msg.sender == owner); + function amIOwner() public pure returns(bool) { +// return (msg.sender == owner); + return true; } function getManyMembers() public view returns(uint) { diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index bad0dbc..4eecfa1 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -1,6 +1,6 @@ pragma solidity ^0.4.22; -import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; +//import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; import "./Susu.sol"; import "./SusuDataStore.sol"; import "./IRegistry.sol"; @@ -21,7 +21,7 @@ contract SusuParent { SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); Susu susu = new Susu(susuDataStore, msg.sender); registry.put(_key, susu); - susu.transferOwnership(msg.sender); +// susu.transferOwnership(msg.sender); } } @@ -33,7 +33,7 @@ contract SusuParent { function upgradeSusu(bytes32 _key) external { address susuAddressOrig = registry.get(_key); Susu susu = Susu(susuAddressOrig); - Susu susuNew = new Susu(susu.susuDataStore(), susu.owner()); + Susu susuNew = new Susu(susu.susuDataStore(), 0x0); // susu.kill(); // Transfer value? registry.put(_key, susuNew); } diff --git a/contracts/SusuRegistry.sol b/contracts/SusuRegistry.sol index acc8a70..f6262af 100644 --- a/contracts/SusuRegistry.sol +++ b/contracts/SusuRegistry.sol @@ -1,12 +1,14 @@ pragma solidity ^0.4.22; -import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; +//import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; import "./IRegistry.sol"; -contract SusuRegistry is IRegistry, Ownable { +// add Ownable +contract SusuRegistry is IRegistry { mapping(bytes32 => address) public registry; - function put(bytes32 _key, address _contractAddress) external onlyOwner { + // add onlyOwner + function put(bytes32 _key, address _contractAddress) external { registry[_key] = _contractAddress; } From eafcd0fccc165d2fffe0befff745c51aadc44f21 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Thu, 16 Aug 2018 16:27:16 -0700 Subject: [PATCH 25/33] fix groupName --- contracts/Susu.sol | 2 +- src/components/DeployPage.js | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index e7134ab..a463da1 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -9,7 +9,7 @@ contract Susu { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - string public version = '0.0.1'; + string constant public version = '0.0.4'; constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index e6cce0f..b32a7b3 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -64,7 +64,7 @@ class DeployPage extends Component { {/**/} {/**/} {/**/} - {/**/} + {/**/} {/**/} {/**/} @@ -108,7 +108,7 @@ class DeployPage extends Component { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; - return instance.createSusu(this.state.key, 2, name, 1, options); + return instance.createSusu(this.state.key, 2, 'name_'+this.state.key, 1, options); }).then((result)=>{console.log('createSusu result:',result);}); } @@ -127,8 +127,8 @@ class DeployPage extends Component { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; - return instance.createSusu(this.state.key, 2, name, 1, options); - }).then((result)=>{console.log('createSusu result:',result);}); + return instance.upgradeSusu(this.state.key, options); + }).then((result)=>{console.log('upgradeSusu result:',result);}); } setSusu2(e) { @@ -163,13 +163,13 @@ class DeployPage extends Component { }); } - // groupName(e) { - // e.preventDefault(); - // this.state.susuContract.groupName((err, groupName)=>{ - // console.log('err:',err, ' groupName:', groupName); - // }); - // } - // + groupName(e) { + e.preventDefault(); + this.state.susuContract1.groupName((err, groupName)=>{ + console.log('err:',err, ' groupName:', groupName); + }); + } + // getManyMembers(e) { // e.preventDefault(); // this.state.susuContract.getManyMembers((err, getManyMembersBig)=>{ From 0d32cc6c681e1f4473bd7dd7439a0fb2a8adcb87 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Fri, 17 Aug 2018 11:25:44 -0700 Subject: [PATCH 26/33] contribute done --- contracts/Susu.sol | 30 +++--- contracts/SusuDataStore.sol | 12 ++- src/components/DeployPage.js | 195 +++++++++++++++++------------------ 3 files changed, 121 insertions(+), 116 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index a463da1..473c654 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -9,7 +9,7 @@ contract Susu { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - string constant public version = '0.0.4'; + string constant public version = '0.0.11'; constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); @@ -21,6 +21,10 @@ contract Susu { return susuDataStore.groupName(); } + function contribAmtWei() public view returns(uint256) { + return susuDataStore.contribAmtWei(); + } + // function pullPayOut() public payable { // require(msg.sender == members[memberIdxToPayNext]); // resetBalances(); @@ -63,11 +67,7 @@ contract Susu { return susuDataStore.getMemberAtIndex(_index); } - function getContributionForMember(address _member) public view returns(uint256) { - return susuDataStore.getContributionForMember(_member); - } - - function amIOwner() public pure returns(bool) { + function amIOwner() external pure returns(bool) { // return (msg.sender == owner); return true; } @@ -76,7 +76,7 @@ contract Susu { return susuDataStore.getManyMembers(); } - function joinGroup() public { + function joinGroup() external { require(!isRecipient(msg.sender)); susuDataStore.addMember(msg.sender); } @@ -91,12 +91,16 @@ contract Susu { return false; } -// function () external payable { -// require(msg.value == contribAmtWei); -// require(isRecipient(msg.sender)); -// require(currentContributions[msg.sender] == 0); -// currentContributions[msg.sender] = msg.value; -// } + function getContributionForMember(address _member) external view returns(uint256) { + return susuDataStore.getContributionForMember(_member); + } + + function () external payable { +// require(msg.value == susuDataStore.contribAmtWei()); + require(isRecipient(msg.sender)); + require(susuDataStore.getContributionForMember(msg.sender) == 0); + susuDataStore.setContributionForMember(msg.sender, msg.value); + } // onlyOwner? // function kill() public pure { diff --git a/contracts/SusuDataStore.sol b/contracts/SusuDataStore.sol index 05fd3dc..0186e58 100644 --- a/contracts/SusuDataStore.sol +++ b/contracts/SusuDataStore.sol @@ -14,20 +14,24 @@ contract SusuDataStore { groupSize = _groupSize; } - function addMember(address _member) public returns(address[]){ + function addMember(address _member) external { members.push(_member); } - function getManyMembers() public view returns(uint) { + function getManyMembers() external view returns(uint) { return members.length; } - function getMemberAtIndex(uint8 _index) public view returns(address) { + function getMemberAtIndex(uint8 _index) external view returns(address) { return members[_index]; } - function getContributionForMember(address _member) public view returns(uint256) { + function getContributionForMember(address _member) external view returns(uint256) { return currentContributions[_member]; } + function setContributionForMember(address _member, uint256 _contribAmtWei) external { + currentContributions[_member] = _contribAmtWei; + } + } diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index b32a7b3..da55bfc 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -7,7 +7,7 @@ import '../App.css' import SusuParentContract from "../../build/contracts/SusuParent"; import SusuOrigContract from "../../build/contracts/SusuOrig"; import SusuContract from "../../build/contracts/Susu"; -// import {BigNumber} from "bignumber.js"; +import {BigNumber} from "bignumber.js"; class DeployPage extends Component { @@ -18,9 +18,9 @@ class DeployPage extends Component { web3: null, isLoading: false, susuParentContract: null, - susuContract1: null, - susuContract2: null, + susuContract: null, key:'key', + contribAmtWei:0, } } @@ -56,26 +56,19 @@ class DeployPage extends Component {
- + - - - - {/**/} - {/**/} - {/**/} + - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} + + + + + + + + +
@@ -108,18 +101,18 @@ class DeployPage extends Component { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; - return instance.createSusu(this.state.key, 2, 'name_'+this.state.key, 1, options); + return instance.createSusu(this.state.key, 2, 'name_'+this.state.key, this.state.web3.toWei(1.0, "ether"), options); }).then((result)=>{console.log('createSusu result:',result);}); } - setSusu1(e) { + setSusu(e) { e.preventDefault(); this.state.susuParentContract.deployed().then((instance)=>{ return instance.getSusu.call(this.state.key); }).then((susuContractAddress)=>{ console.log('susuContractAddress:',susuContractAddress); const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); - this.setState({susuContract1: susuContract}); + this.setState({susuContract: susuContract}); }); } @@ -131,98 +124,102 @@ class DeployPage extends Component { }).then((result)=>{console.log('upgradeSusu result:',result);}); } - setSusu2(e) { + version(e) { e.preventDefault(); - this.state.susuParentContract.deployed().then((instance)=>{ - return instance.getSusu.call(this.state.key); - }).then((susuContractAddress)=>{ - console.log('susuContractAddress:',susuContractAddress); - const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); - this.setState({susuContract2: susuContract}); + this.state.susuContract.version((err, version)=>{ + console.log('err:',err, ' version:', version); }); } - // foo(e) { - // e.preventDefault(); - // this.state.susuContract.foo((err, foo)=>{ - // console.log('err:',err, ' foo:', foo); - // }); - // } + groupName(e) { + e.preventDefault(); + this.state.susuContract.groupName((err, groupName)=>{ + console.log('err:',err, ' groupName:', groupName); + }); + } - version1(e) { + getManyMembers(e) { e.preventDefault(); - this.state.susuContract1.version((err, version1)=>{ - console.log('err:',err, ' version1:', version1); + this.state.susuContract.getManyMembers((err, getManyMembersBig)=>{ + let bigNumber = new BigNumber(getManyMembersBig); + const getManyMembers = bigNumber.toNumber(); + console.log('err:',err, ' getManyMembers:', getManyMembers); }); } - version2(e) { + contribute(e) { + e.preventDefault(); + + this.state.web3.eth.sendTransaction( + { + from: this.state.web3.eth.accounts[0], + to: this.state.susuContract.address, + value:this.state.contribAmtWei, + gas:2000000 + }, + (err)=>{ + if(typeof err === 'undefined' || !err) { + console.log('contribute done'); + } else { + console.error(err); + } + }); + } + + contribAmtWei(e) { e.preventDefault(); - this.state.susuContract2.version((err, version2)=>{ - console.log('err:',err, ' version2:', version2); + this.state.susuContract.contribAmtWei((err, contribAmtWeiBig)=>{ + let bigNumber = new BigNumber(contribAmtWeiBig); + const contribAmtWei = bigNumber.toNumber(); + console.log('err:',err, ' contribAmtWei:', contribAmtWei); + this.setState({contribAmtWei: contribAmtWei}); }); } - groupName(e) { + getContributionForMember(e) { e.preventDefault(); - this.state.susuContract1.groupName((err, groupName)=>{ - console.log('err:',err, ' groupName:', groupName); + this.state.susuContract.getContributionForMember(this.state.web3.eth.accounts[0], (err, getContributionForMemberBig)=>{ + let bigNumber = new BigNumber(getContributionForMemberBig); + const getContributionForMember = this.state.web3.fromWei(bigNumber, 'ether').toNumber(); + console.log('err:',err, ' getContributionForMember:', getContributionForMember); + }); + } + + getMemberAtIndex0(e) { + e.preventDefault(); + this.state.susuContract.getMemberAtIndex(0, (err, memberAddress)=>{ + console.log('err:',err, ' memberAddress0:', memberAddress); }); } - // getManyMembers(e) { - // e.preventDefault(); - // this.state.susuContract.getManyMembers((err, getManyMembersBig)=>{ - // let bigNumber = new BigNumber(getManyMembersBig); - // const getManyMembers = bigNumber.toNumber(); - // console.log('err:',err, ' getManyMembers:', getManyMembers); - // }); - // } - // - // getContributionForMember(e) { - // e.preventDefault(); - // this.state.susuContract.getContributionForMember(this.state.web3.eth.accounts[0], (err, getContributionForMemberBig)=>{ - // let bigNumber = new BigNumber(getContributionForMemberBig); - // const getContributionForMember = bigNumber.toNumber(); - // console.log('err:',err, ' getContributionForMember:', getContributionForMember); - // }); - // } - // - // getMemberAtIndex0(e) { - // e.preventDefault(); - // this.state.susuContract.getMemberAtIndex(0, (err, memberAddress)=>{ - // console.log('err:',err, ' memberAddress0:', memberAddress); - // }); - // } - // - // getMemberAtIndex1(e) { - // e.preventDefault(); - // this.state.susuContract.getMemberAtIndex(1, (err, memberAddress)=>{ - // console.log('err:',err, ' memberAddress1:', memberAddress); - // }); - // } - // - // owner(e) { - // e.preventDefault(); - // const options = {from: this.state.web3.eth.accounts[0]}; - // this.state.susuContract.owner(options, (err, owner)=>{ - // console.log('err:',err, ' owner:', owner, ' =?me', (owner===this.state.web3.eth.accounts[0])); - // }); - // } - // - // amIOwner(e) { - // e.preventDefault(); - // const options = {from: this.state.web3.eth.accounts[0]}; - // this.state.susuContract.amIOwner(options, (err, amIOwner)=>{ - // console.log('err:',err, ' amIOwner:', amIOwner); - // }); - // } - // - // joinGroup(e) { - // e.preventDefault(); - // const options = {from: this.state.web3.eth.accounts[0], gas: 2000000}; - // this.state.susuContract.joinGroup(options, (err, resp)=>{console.log('err:',err, ' resp:', resp);}); - // } + getMemberAtIndex1(e) { + e.preventDefault(); + this.state.susuContract.getMemberAtIndex(1, (err, memberAddress)=>{ + console.log('err:',err, ' memberAddress1:', memberAddress); + }); + } + + owner(e) { + e.preventDefault(); + const options = {from: this.state.web3.eth.accounts[0]}; + this.state.susuContract.owner(options, (err, owner)=>{ + console.log('err:',err, ' owner:', owner, ' =?me', (owner===this.state.web3.eth.accounts[0])); + }); + } + + amIOwner(e) { + e.preventDefault(); + const options = {from: this.state.web3.eth.accounts[0]}; + this.state.susuContract.amIOwner(options, (err, amIOwner)=>{ + console.log('err:',err, ' amIOwner:', amIOwner); + }); + } + + joinGroup(e) { + e.preventDefault(); + const options = {from: this.state.web3.eth.accounts[0], gas: 2000000}; + this.state.susuContract.joinGroup(options, (err, resp)=>{console.log('err:',err, ' resp:', resp);}); + } clickCreate(e) { e.preventDefault(); From e90226a1d03ff9c896dc93a34bdce857a7417feb Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Fri, 17 Aug 2018 11:39:53 -0700 Subject: [PATCH 27/33] fix owner --- contracts/Susu.sol | 14 +++++++------- contracts/SusuParent.sol | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index 473c654..f71f22f 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -1,15 +1,14 @@ pragma solidity ^0.4.22; -//import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; +import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; //import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; import "./SusuDataStore.sol"; -// add Ownable -contract Susu { +contract Susu is Ownable { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - string constant public version = '0.0.11'; + string constant public version = '0.0.12'; constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); @@ -26,6 +25,8 @@ contract Susu { } // function pullPayOut() public payable { +// // TODO: require group is full +// // TODO: require everyone has paid // require(msg.sender == members[memberIdxToPayNext]); // resetBalances(); // iterateMemberToPayNext(); @@ -67,9 +68,8 @@ contract Susu { return susuDataStore.getMemberAtIndex(_index); } - function amIOwner() external pure returns(bool) { -// return (msg.sender == owner); - return true; + function amIOwner() external view returns(bool) { + return (msg.sender == owner); } function getManyMembers() public view returns(uint) { diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index 4eecfa1..3d25091 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -21,7 +21,7 @@ contract SusuParent { SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); Susu susu = new Susu(susuDataStore, msg.sender); registry.put(_key, susu); -// susu.transferOwnership(msg.sender); + susu.transferOwnership(msg.sender); } } From c544e6bc5159546c65a230ac03a1836b6053d8bb Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Fri, 17 Aug 2018 13:15:13 -0700 Subject: [PATCH 28/33] Starting to update Group Page --- contracts/Susu.sol | 14 +- src/App.js | 2 +- src/components/ActionButtons.js | 4 +- src/components/DeployPage.js | 313 ++++++++++++++++---------------- src/components/GroupPage.js | 41 +++-- 5 files changed, 199 insertions(+), 175 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index f71f22f..a8ad400 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -8,7 +8,7 @@ contract Susu is Ownable { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - string constant public version = '0.0.12'; + string constant public version = '0.0.13'; constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); @@ -16,14 +16,22 @@ contract Susu is Ownable { susuDataStore.addMember(_newOwner); } - function groupName() public view returns(string) { + function groupName() external view returns(string) { return susuDataStore.groupName(); } - function contribAmtWei() public view returns(uint256) { + function contribAmtWei() external view returns(uint256) { return susuDataStore.contribAmtWei(); } + function memberIdxToPayNext() external view returns(uint) { + return susuDataStore.memberIdxToPayNext(); + } + + function groupSize() external view returns(uint8) { + return susuDataStore.groupSize(); + } + // function pullPayOut() public payable { // // TODO: require group is full // // TODO: require everyone has paid diff --git a/src/App.js b/src/App.js index ec0c0f7..e166725 100644 --- a/src/App.js +++ b/src/App.js @@ -21,7 +21,7 @@ class App extends Component {
- +
diff --git a/src/components/ActionButtons.js b/src/components/ActionButtons.js index 907d189..b439184 100644 --- a/src/components/ActionButtons.js +++ b/src/components/ActionButtons.js @@ -47,7 +47,7 @@ class ActionButtons extends Component { from:this.props.myAddress, to:this.props.susuContract.address, value:this.props.web3.toWei(this.props.contribAmt, "ether"), - gas:60000 + gas:200000 }, (err)=>{ this.setState({isLoading:false}); @@ -81,7 +81,7 @@ class ActionButtons extends Component { e.preventDefault(); this.setState({isLoading:true}); this.props.susuContract.joinGroup( - {from:this.props.myAddress, gas:60000}, + {from:this.props.myAddress, gas:200000}, (err)=>{ this.setState({isLoading:false}); if(typeof err === 'undefined' || !err) { diff --git a/src/components/DeployPage.js b/src/components/DeployPage.js index da55bfc..d45939c 100644 --- a/src/components/DeployPage.js +++ b/src/components/DeployPage.js @@ -1,13 +1,13 @@ import React, { Component } from 'react' -import contract from 'truffle-contract' +// import contract from 'truffle-contract' import getWeb3 from '../utils/getWeb3' import '../App.css' import SusuParentContract from "../../build/contracts/SusuParent"; -import SusuOrigContract from "../../build/contracts/SusuOrig"; -import SusuContract from "../../build/contracts/Susu"; -import {BigNumber} from "bignumber.js"; +// import SusuOrigContract from "../../build/contracts/SusuOrig"; +// import SusuContract from "../../build/contracts/Susu"; +// import {BigNumber} from "bignumber.js"; class DeployPage extends Component { @@ -44,8 +44,6 @@ class DeployPage extends Component { const provider = new this.state.web3.providers.HttpProvider("http://127.0.0.1:7545"); susuParentContract.setProvider(provider); this.setState({susuParentContract: susuParentContract}); - - console.log('accounts:',this.state.web3.eth.accounts); } render() { @@ -55,20 +53,20 @@ class DeployPage extends Component {
- - - - - - - - - - - - - - + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/}
@@ -96,154 +94,155 @@ class DeployPage extends Component { ); }// render() - - createSusu(e) { - e.preventDefault(); - this.state.susuParentContract.deployed().then((instance)=>{ - const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; - return instance.createSusu(this.state.key, 2, 'name_'+this.state.key, this.state.web3.toWei(1.0, "ether"), options); - }).then((result)=>{console.log('createSusu result:',result);}); - } - - setSusu(e) { - e.preventDefault(); - this.state.susuParentContract.deployed().then((instance)=>{ - return instance.getSusu.call(this.state.key); - }).then((susuContractAddress)=>{ - console.log('susuContractAddress:',susuContractAddress); - const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); - this.setState({susuContract: susuContract}); - }); - } - - upgradeSusu(e) { - e.preventDefault(); - this.state.susuParentContract.deployed().then((instance)=>{ - const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; - return instance.upgradeSusu(this.state.key, options); - }).then((result)=>{console.log('upgradeSusu result:',result);}); - } - - version(e) { - e.preventDefault(); - this.state.susuContract.version((err, version)=>{ - console.log('err:',err, ' version:', version); - }); - } - - groupName(e) { - e.preventDefault(); - this.state.susuContract.groupName((err, groupName)=>{ - console.log('err:',err, ' groupName:', groupName); - }); - } - - getManyMembers(e) { - e.preventDefault(); - this.state.susuContract.getManyMembers((err, getManyMembersBig)=>{ - let bigNumber = new BigNumber(getManyMembersBig); - const getManyMembers = bigNumber.toNumber(); - console.log('err:',err, ' getManyMembers:', getManyMembers); - }); - } - - contribute(e) { - e.preventDefault(); - - this.state.web3.eth.sendTransaction( - { - from: this.state.web3.eth.accounts[0], - to: this.state.susuContract.address, - value:this.state.contribAmtWei, - gas:2000000 - }, - (err)=>{ - if(typeof err === 'undefined' || !err) { - console.log('contribute done'); - } else { - console.error(err); - } - }); - } - - contribAmtWei(e) { - e.preventDefault(); - this.state.susuContract.contribAmtWei((err, contribAmtWeiBig)=>{ - let bigNumber = new BigNumber(contribAmtWeiBig); - const contribAmtWei = bigNumber.toNumber(); - console.log('err:',err, ' contribAmtWei:', contribAmtWei); - this.setState({contribAmtWei: contribAmtWei}); - }); - } - - getContributionForMember(e) { - e.preventDefault(); - this.state.susuContract.getContributionForMember(this.state.web3.eth.accounts[0], (err, getContributionForMemberBig)=>{ - let bigNumber = new BigNumber(getContributionForMemberBig); - const getContributionForMember = this.state.web3.fromWei(bigNumber, 'ether').toNumber(); - console.log('err:',err, ' getContributionForMember:', getContributionForMember); - }); - } - - getMemberAtIndex0(e) { - e.preventDefault(); - this.state.susuContract.getMemberAtIndex(0, (err, memberAddress)=>{ - console.log('err:',err, ' memberAddress0:', memberAddress); - }); - } - - getMemberAtIndex1(e) { - e.preventDefault(); - this.state.susuContract.getMemberAtIndex(1, (err, memberAddress)=>{ - console.log('err:',err, ' memberAddress1:', memberAddress); - }); - } - - owner(e) { - e.preventDefault(); - const options = {from: this.state.web3.eth.accounts[0]}; - this.state.susuContract.owner(options, (err, owner)=>{ - console.log('err:',err, ' owner:', owner, ' =?me', (owner===this.state.web3.eth.accounts[0])); - }); - } - - amIOwner(e) { - e.preventDefault(); - const options = {from: this.state.web3.eth.accounts[0]}; - this.state.susuContract.amIOwner(options, (err, amIOwner)=>{ - console.log('err:',err, ' amIOwner:', amIOwner); - }); - } - - joinGroup(e) { - e.preventDefault(); - const options = {from: this.state.web3.eth.accounts[0], gas: 2000000}; - this.state.susuContract.joinGroup(options, (err, resp)=>{console.log('err:',err, ' resp:', resp);}); - } + // createSusu(e) { + // e.preventDefault(); + // this.state.susuParentContract.deployed().then((instance)=>{ + // const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; + // return instance.createSusu(this.state.key, 2, 'name_'+this.state.key, this.state.web3.toWei(1.0, "ether"), options); + // }).then((result)=>{console.log('createSusu result:',result);}); + // } + // + // setSusu(e) { + // e.preventDefault(); + // this.state.susuParentContract.deployed().then((instance)=>{ + // return instance.getSusu.call(this.state.key); + // }).then((susuContractAddress)=>{ + // console.log('susuContractAddress:',susuContractAddress); + // const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); + // this.setState({susuContract: susuContract}); + // }); + // } + // + // upgradeSusu(e) { + // e.preventDefault(); + // this.state.susuParentContract.deployed().then((instance)=>{ + // const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; + // return instance.upgradeSusu(this.state.key, options); + // }).then((result)=>{console.log('upgradeSusu result:',result);}); + // } + // + // version(e) { + // e.preventDefault(); + // this.state.susuContract.version((err, version)=>{ + // console.log('err:',err, ' version:', version); + // }); + // } + // + // groupName(e) { + // e.preventDefault(); + // this.state.susuContract.groupName((err, groupName)=>{ + // console.log('err:',err, ' groupName:', groupName); + // }); + // } + // + // getManyMembers(e) { + // e.preventDefault(); + // this.state.susuContract.getManyMembers((err, getManyMembersBig)=>{ + // let bigNumber = new BigNumber(getManyMembersBig); + // const getManyMembers = bigNumber.toNumber(); + // console.log('err:',err, ' getManyMembers:', getManyMembers); + // }); + // } + // + // contribute(e) { + // e.preventDefault(); + // + // this.state.web3.eth.sendTransaction( + // { + // from: this.state.web3.eth.accounts[0], + // to: this.state.susuContract.address, + // value:this.state.contribAmtWei, + // gas:2000000 + // }, + // (err)=>{ + // if(typeof err === 'undefined' || !err) { + // console.log('contribute done'); + // } else { + // console.error(err); + // } + // }); + // } + // + // contribAmtWei(e) { + // e.preventDefault(); + // this.state.susuContract.contribAmtWei((err, contribAmtWeiBig)=>{ + // let bigNumber = new BigNumber(contribAmtWeiBig); + // const contribAmtWei = bigNumber.toNumber(); + // console.log('err:',err, ' contribAmtWei:', contribAmtWei); + // this.setState({contribAmtWei: contribAmtWei}); + // }); + // } + // + // getContributionForMember(e) { + // e.preventDefault(); + // this.state.susuContract.getContributionForMember(this.state.web3.eth.accounts[0], (err, getContributionForMemberBig)=>{ + // let bigNumber = new BigNumber(getContributionForMemberBig); + // const getContributionForMember = this.state.web3.fromWei(bigNumber, 'ether').toNumber(); + // console.log('err:',err, ' getContributionForMember:', getContributionForMember); + // }); + // } + // + // getMemberAtIndex0(e) { + // e.preventDefault(); + // this.state.susuContract.getMemberAtIndex(0, (err, memberAddress)=>{ + // console.log('err:',err, ' memberAddress0:', memberAddress); + // }); + // } + // + // getMemberAtIndex1(e) { + // e.preventDefault(); + // this.state.susuContract.getMemberAtIndex(1, (err, memberAddress)=>{ + // console.log('err:',err, ' memberAddress1:', memberAddress); + // }); + // } + // + // owner(e) { + // e.preventDefault(); + // const options = {from: this.state.web3.eth.accounts[0]}; + // this.state.susuContract.owner(options, (err, owner)=>{ + // console.log('err:',err, ' owner:', owner, ' =?me', (owner===this.state.web3.eth.accounts[0])); + // }); + // } + // + // amIOwner(e) { + // e.preventDefault(); + // const options = {from: this.state.web3.eth.accounts[0]}; + // this.state.susuContract.amIOwner(options, (err, amIOwner)=>{ + // console.log('err:',err, ' amIOwner:', amIOwner); + // }); + // } + // + // joinGroup(e) { + // e.preventDefault(); + // const options = {from: this.state.web3.eth.accounts[0], gas: 2000000}; + // this.state.susuContract.joinGroup(options, (err, resp)=>{console.log('err:',err, ' resp:', resp);}); + // } clickCreate(e) { e.preventDefault(); this.setState({isLoading:true}); - const susuContract = contract(SusuOrigContract); - const { unlinked_binary, abi } = susuContract; - const newContract = this.state.web3.eth.contract(abi); - const options = { from: this.state.web3.eth.accounts[0], data: unlinked_binary, gas: 2000000 }; + const options = { from: this.state.web3.eth.accounts[0], gas: 2000000 }; const groupSize = document.getElementById('group_size').value; const groupName = document.getElementById('group_name').value; const contribAmtEth = document.getElementById('contrib_amt').value; const contribAmtWei = this.state.web3.toWei(contribAmtEth, 'ether'); - newContract.new(groupSize, groupName, contribAmtWei, options, this.newContractCallback()); - } - newContractCallback() { - return (err, newContract) => { - const { address } = newContract; - if(typeof address !== 'undefined' ) { - window.location.href = '/'+address; - } - } + this.state.susuParentContract.deployed().then((instance)=>{ + return instance.createSusu(groupName, groupSize, groupName, contribAmtWei, options); + }).then(()=>{ + window.location.href = '/'+groupName; + }); } + + // newContractCallback() { + // return (err, newContract) => { + // const { address } = newContract; + // if(typeof address !== 'undefined' ) { + // + // } + // } + // } } DeployPage.defaultProps = { diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index 46f3a0e..e778995 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -1,6 +1,6 @@ import React, { Component } from 'react' -import SusuOrigContract from '../../build/contracts/SusuOrig.json' +// import SusuOrigContract from '../../build/contracts/SusuOrig.json' import getWeb3 from '../utils/getWeb3' import {BigNumber} from 'bignumber.js'; @@ -12,6 +12,8 @@ import PartnerRow from "./PartnerRow"; import GroupInfo from "./GroupInfo"; import ActionButtons from "./ActionButtons"; import PartnerRowEmpty from "./PartnerRowEmpty"; +import SusuParentContract from "../../build/contracts/SusuParent"; +import SusuContract from "../../build/contracts/Susu"; class GroupPage extends Component { @@ -21,15 +23,16 @@ class GroupPage extends Component { this.state = { web3: null, susuContract: null, + susuParentContract: null, myAddress: '', contribAmt: 0, - groupName: '---', payoutFrequency: 'monthly', manyMembers: 0, groupSize: 0, ownerAddress: '', partnerObjects: [], contractAddress: props.match.params.contractAddress, + groupName: props.match.params.groupName, myContrib:0.0, memberAddrToPayNext:0, } @@ -51,14 +54,28 @@ class GroupPage extends Component { } instantiateContract() { - const susuContract = this.state.web3.eth.contract(SusuOrigContract.abi).at(this.state.contractAddress); - this.setState({susuContract:susuContract}); + const contract = require("truffle-contract"); + const susuParentContract = contract(SusuParentContract); + const provider = new this.state.web3.providers.HttpProvider("http://127.0.0.1:7545"); + susuParentContract.setProvider(provider); + this.setState({susuParentContract: susuParentContract}); + + this.state.susuParentContract.deployed().then((instance)=>{ + return instance.getSusu.call(this.state.groupName); + }).then((susuContractAddress)=>{ + console.log('susuContractAddress:',susuContractAddress); + const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); + this.setState({susuContract: susuContract}); + this.initState(); + }); + } + initState() { let _this = this; this.state.web3.eth.getAccounts(function(error, accounts) { const myAddress = accounts[0]; _this.setState({myAddress: myAddress}); - susuContract.getContributionForMember(myAddress, (err, contribAmtWei)=>{ + _this.state.susuContract.getContributionForMember(myAddress, (err, contribAmtWei)=>{ let bigNumber = new BigNumber(contribAmtWei); const contribAmt = _this.state.web3.fromWei(bigNumber, 'ether').toNumber(); _this.setState({myContrib:contribAmt}); @@ -72,33 +89,33 @@ class GroupPage extends Component { this.setState({ partnerObjects: partnerObjects }); } - susuContract.groupName((err, groupName)=>{ + this.state.susuContract.groupName((err, groupName)=>{ this.setState({groupName:groupName}); }); - susuContract.memberIdxToPayNext((err, memberIdxToPayNextBig)=>{ + this.state.susuContract.memberIdxToPayNext((err, memberIdxToPayNextBig)=>{ let bigNumber = new BigNumber(memberIdxToPayNextBig); const memberIdxToPayNext = bigNumber.toNumber(); - susuContract.getMemberAtIndex(memberIdxToPayNext, (err, memberAddrToPayNext)=>{ + this.state.susuContract.getMemberAtIndex(memberIdxToPayNext, (err, memberAddrToPayNext)=>{ this.setState({memberAddrToPayNext:memberAddrToPayNext}); }); }); - susuContract.contribAmtWei((err, contribAmtWei)=>{ + this.state.susuContract.contribAmtWei((err, contribAmtWei)=>{ let bigNumber = new BigNumber(contribAmtWei); const contribAmt = this.state.web3.fromWei(bigNumber, 'ether').toNumber(); this.setState({contribAmt:contribAmt}); }); - susuContract.owner((err, ownerAddress)=>{ + this.state.susuContract.owner((err, ownerAddress)=>{ this.setState({ownerAddress:ownerAddress}); - susuContract.getManyMembers((err, manyMembersBig)=>{ + this.state.susuContract.getManyMembers((err, manyMembersBig)=>{ let bigNumber = new BigNumber(manyMembersBig); const manyMembers = bigNumber.toNumber(); this.setState({manyMembers:manyMembers}); - susuContract.groupSize((err, groupSizeBig)=>{ + this.state.susuContract.groupSize((err, groupSizeBig)=>{ let bigNumber = new BigNumber(groupSizeBig); const groupSize = bigNumber.toNumber(); this.setState({groupSize:groupSize}); From 76a8b45e58b29a879b38a9c32ce0a4ff8dbf261f Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sat, 18 Aug 2018 10:19:18 -0700 Subject: [PATCH 29/33] pullPayOut --- contracts/Susu.sol | 73 ++++++++++++++++++------------------- contracts/SusuDataStore.sol | 6 ++- src/components/GroupInfo.js | 10 +++++ src/components/GroupPage.js | 12 +++++- 4 files changed, 61 insertions(+), 40 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index a8ad400..13b6078 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -1,14 +1,16 @@ pragma solidity ^0.4.22; import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; -//import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; +import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol"; import "./SusuDataStore.sol"; contract Susu is Ownable { + using SafeMath for uint; + SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - string constant public version = '0.0.13'; + string constant public version = '0.0.14'; constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); @@ -20,27 +22,27 @@ contract Susu is Ownable { return susuDataStore.groupName(); } - function contribAmtWei() external view returns(uint256) { + function contribAmtWei() public view returns(uint256) { return susuDataStore.contribAmtWei(); } - function memberIdxToPayNext() external view returns(uint) { + function memberIdxToPayNext() public view returns(uint) { return susuDataStore.memberIdxToPayNext(); } - function groupSize() external view returns(uint8) { + function groupSize() public view returns(uint8) { return susuDataStore.groupSize(); } -// function pullPayOut() public payable { -// // TODO: require group is full -// // TODO: require everyone has paid -// require(msg.sender == members[memberIdxToPayNext]); -// resetBalances(); -// iterateMemberToPayNext(); -// msg.sender.transfer(members.length * contribAmtWei); -// } -// + function pullPayOut() public payable { + // TODO: require group is full + // TODO: require everyone has paid + require(msg.sender == getMemberAtIndex(memberIdxToPayNext())); + resetBalances(); + iterateMemberToPayNext(); + msg.sender.transfer(getManyMembers() * contribAmtWei()); + } + // function everyonePaid() private view returns (bool) { // for (uint i = 0; i < members.length ; i++) // { @@ -49,30 +51,27 @@ contract Susu is Ownable { // } // return true; // } -// -// function resetBalances() private { -// for (uint i = 0; i < members.length ; i++) -// { -// currentContributions[members[i]] = 0; -// } -// } -// -// function iterateMemberToPayNext() private { -// for (uint i = 0; i < members.length ; i++) -// { -// if(members[i] == members[memberIdxToPayNext]) { -// if(i < members.length - 1) { -// memberIdxToPayNext = i.add(1); -// return; -// } -// -// memberIdxToPayNext = 0; -// return; -// } -// } -// } - function getMemberAtIndex(uint8 _index) public view returns(address) { + function resetBalances() private { + for (uint i = 0; i < susuDataStore.getManyMembers(); i++) + { + address member = susuDataStore.getMemberAtIndex(i); + susuDataStore.setContributionForMember(member, 0); + } + } + + function iterateMemberToPayNext() private { + uint _memberIdxToPayNext = susuDataStore.memberIdxToPayNext(); + _memberIdxToPayNext++; + uint manyMembers = susuDataStore.getManyMembers(); + if(_memberIdxToPayNext == manyMembers) { + _memberIdxToPayNext = 0; + } + susuDataStore.setMemberIdxToPayNext(_memberIdxToPayNext); + // TODO: Why was there a for-loop here? Check SusuOrig. Maybe it is needed? + } + + function getMemberAtIndex(uint _index) public view returns(address) { return susuDataStore.getMemberAtIndex(_index); } diff --git a/contracts/SusuDataStore.sol b/contracts/SusuDataStore.sol index 0186e58..6155365 100644 --- a/contracts/SusuDataStore.sol +++ b/contracts/SusuDataStore.sol @@ -22,7 +22,7 @@ contract SusuDataStore { return members.length; } - function getMemberAtIndex(uint8 _index) external view returns(address) { + function getMemberAtIndex(uint _index) external view returns(address) { return members[_index]; } @@ -34,4 +34,8 @@ contract SusuDataStore { currentContributions[_member] = _contribAmtWei; } + function setMemberIdxToPayNext(uint _memberIdxToPayNext) external { + memberIdxToPayNext = _memberIdxToPayNext; + } + } diff --git a/src/components/GroupInfo.js b/src/components/GroupInfo.js index 21cce29..f266b68 100644 --- a/src/components/GroupInfo.js +++ b/src/components/GroupInfo.js @@ -16,6 +16,14 @@ class GroupInfo extends Component { + + + + + + + +
Contribution Amt (eth): {this.props.contribAmt}
Contract Address:{this.props.contractAddress}
Contract Version:{this.props.contractVersion}
); @@ -26,6 +34,8 @@ class GroupInfo extends Component { GroupInfo.defaultProps = { groupName: 'groupName not set', contribAmt: -1, + contractAddress: 'contractAddress not set', + contractVersion: 'contractVersion not set', }; export default GroupInfo diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index e778995..14cbe63 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -31,10 +31,11 @@ class GroupPage extends Component { groupSize: 0, ownerAddress: '', partnerObjects: [], - contractAddress: props.match.params.contractAddress, groupName: props.match.params.groupName, myContrib:0.0, memberAddrToPayNext:0, + susuContractAddress: '', + susuContractVersion: '', } } @@ -66,6 +67,7 @@ class GroupPage extends Component { console.log('susuContractAddress:',susuContractAddress); const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); this.setState({susuContract: susuContract}); + this.setState({susuContractAddress: susuContractAddress}); this.initState(); }); } @@ -93,6 +95,10 @@ class GroupPage extends Component { this.setState({groupName:groupName}); }); + this.state.susuContract.version((err, susuContractVersion)=>{ + this.setState({susuContractVersion:susuContractVersion}); + }); + this.state.susuContract.memberIdxToPayNext((err, memberIdxToPayNextBig)=>{ let bigNumber = new BigNumber(memberIdxToPayNextBig); const memberIdxToPayNext = bigNumber.toNumber(); @@ -138,12 +144,14 @@ class GroupPage extends Component { let isGroupTerminated = false; let isMember = this.isMember(); let isMemberToPayNext = this.state.memberAddrToPayNext===this.state.myAddress; + let contractAddress = this.state.susuContractAddress; + let contractVersion = this.state.susuContractVersion; return (
- + {this.createPartnerRows()} From 8211dfab5b173c9470f3c2be7437aad109161d74 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sat, 18 Aug 2018 11:08:28 -0700 Subject: [PATCH 30/33] Upgrade button working --- contracts/Susu.sol | 11 +++++++---- contracts/SusuParent.sol | 6 +++--- src/components/ActionButtons.js | 19 ++++++++++++++++++- src/components/GroupPage.js | 3 ++- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index 13b6078..1e2bfc2 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -10,12 +10,13 @@ contract Susu is Ownable { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - string constant public version = '0.0.14'; + string constant public version = '0.0.19'; constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); require(susuDataStore.groupSize() <= MAX_MEMBERS); susuDataStore.addMember(_newOwner); + transferOwnership(_newOwner); } function groupName() external view returns(string) { @@ -103,17 +104,19 @@ contract Susu is Ownable { } function () external payable { -// require(msg.value == susuDataStore.contribAmtWei()); + require(msg.value == susuDataStore.contribAmtWei()); require(isRecipient(msg.sender)); require(susuDataStore.getContributionForMember(msg.sender) == 0); susuDataStore.setContributionForMember(msg.sender, msg.value); +// address(susuDataStore).transfer(1); } // onlyOwner? -// function kill() public pure { + function transferValue(address _susuNew) external { // ???=> var tokenBalance = susuDataStore.balanceOf(this); // ???=> tokenLedger.transfer(_upgradedSusu, tokenBalance); // ???=> selfdestruct(_upgradedSusu); -// } + _susuNew.transfer(address(this).balance); + } } diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index 3d25091..eb022fc 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -9,6 +9,7 @@ import "./IRegistry.sol"; contract SusuParent { IRegistry public registry; + string constant public version = '0.0.2'; constructor(address _registry) public { registry = IRegistry(_registry); @@ -21,7 +22,6 @@ contract SusuParent { SusuDataStore susuDataStore = new SusuDataStore(_groupSize, _groupName, _contribAmtWei); Susu susu = new Susu(susuDataStore, msg.sender); registry.put(_key, susu); - susu.transferOwnership(msg.sender); } } @@ -33,8 +33,8 @@ contract SusuParent { function upgradeSusu(bytes32 _key) external { address susuAddressOrig = registry.get(_key); Susu susu = Susu(susuAddressOrig); - Susu susuNew = new Susu(susu.susuDataStore(), 0x0); -// susu.kill(); // Transfer value? + Susu susuNew = new Susu(susu.susuDataStore(), susu.owner()); +// susu.transferValue(susuNew); registry.put(_key, susuNew); } diff --git a/src/components/ActionButtons.js b/src/components/ActionButtons.js index b439184..2ae8f70 100644 --- a/src/components/ActionButtons.js +++ b/src/components/ActionButtons.js @@ -17,6 +17,7 @@ class ActionButtons extends Component { let contributeBtn = ; let pullPayOutBtn = ; let joinBtn = ; + let upgradeBtn = ; if(!this.props.isGroupFull && !this.props.isMember){ btns.push(joinBtn); @@ -27,6 +28,9 @@ class ActionButtons extends Component { if(this.props.isMemberToPayNext) { btns.push(pullPayOutBtn); } + if(this.props.isOwner) { + btns.push(upgradeBtn); + } } return ( @@ -47,7 +51,7 @@ class ActionButtons extends Component { from:this.props.myAddress, to:this.props.susuContract.address, value:this.props.web3.toWei(this.props.contribAmt, "ether"), - gas:200000 + gas:2000000 }, (err)=>{ this.setState({isLoading:false}); @@ -93,6 +97,17 @@ class ActionButtons extends Component { } ); } + + clickUpgrade(e) { + e.preventDefault(); + this.setState({isLoading:true}); + this.props.susuParentContract.deployed().then((instance)=>{ + const options = { from: this.props.myAddress, gas: 2000000 }; + return instance.upgradeSusu(this.props.groupName, options); + }).then((a,b)=>{ + location.reload(); + }); + } } ActionButtons.defaultProps = { @@ -101,12 +116,14 @@ ActionButtons.defaultProps = { isGroupTerminated: false, isMember: false, susuContract: null, + susuParentContract: null, myAddress: '', web3:null, contribAmt:0.0, myContrib:0.0, isReadyToPayout:false, isMemberToPayNext:false, + groupName: '', }; export default ActionButtons diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index 14cbe63..265cf86 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -64,7 +64,6 @@ class GroupPage extends Component { this.state.susuParentContract.deployed().then((instance)=>{ return instance.getSusu.call(this.state.groupName); }).then((susuContractAddress)=>{ - console.log('susuContractAddress:',susuContractAddress); const susuContract = this.state.web3.eth.contract(SusuContract.abi).at(susuContractAddress); this.setState({susuContract: susuContract}); this.setState({susuContractAddress: susuContractAddress}); @@ -166,12 +165,14 @@ class GroupPage extends Component { isGroupTerminated={isGroupTerminated} isMember={isMember} susuContract={this.state.susuContract} + susuParentContract={this.state.susuParentContract} myAddress={this.state.myAddress} web3={this.state.web3} contribAmt={this.state.contribAmt} myContrib={this.state.myContrib} isReadyToPayout={this.isReadyToPayout()} isMemberToPayNext={isMemberToPayNext} + groupName={this.state.groupName} /> From 9d6882cfd92cf39b614d8cb8013e4f5f49da5406 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sat, 18 Aug 2018 12:16:07 -0700 Subject: [PATCH 31/33] Fix upgrade so owner is not added multiple times. value tx still broke --- contracts/Susu.sol | 18 +++++++++--------- contracts/SusuParent.sol | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index 1e2bfc2..db40025 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -10,12 +10,14 @@ contract Susu is Ownable { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - string constant public version = '0.0.19'; + string constant public version = '0.0.21'; constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); require(susuDataStore.groupSize() <= MAX_MEMBERS); - susuDataStore.addMember(_newOwner); + if(susuDataStore.getManyMembers()==0) { + susuDataStore.addMember(_newOwner); + } transferOwnership(_newOwner); } @@ -104,19 +106,17 @@ contract Susu is Ownable { } function () external payable { - require(msg.value == susuDataStore.contribAmtWei()); +// require(msg.value == susuDataStore.contribAmtWei()); require(isRecipient(msg.sender)); require(susuDataStore.getContributionForMember(msg.sender) == 0); susuDataStore.setContributionForMember(msg.sender, msg.value); -// address(susuDataStore).transfer(1); } // onlyOwner? - function transferValue(address _susuNew) external { -// ???=> var tokenBalance = susuDataStore.balanceOf(this); -// ???=> tokenLedger.transfer(_upgradedSusu, tokenBalance); -// ???=> selfdestruct(_upgradedSusu); - _susuNew.transfer(address(this).balance); + function transferValue(address _susuNew) external returns(bool){ +// TODO: selfdestruct(_upgradedSusu); +// _susuNew.transfer(address(this).balance); + return _susuNew.send(1); } } diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index eb022fc..8bc3c2f 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -34,7 +34,7 @@ contract SusuParent { address susuAddressOrig = registry.get(_key); Susu susu = Susu(susuAddressOrig); Susu susuNew = new Susu(susu.susuDataStore(), susu.owner()); -// susu.transferValue(susuNew); + susu.transferValue(susuNew); registry.put(_key, susuNew); } From 71d065b96645f2beefd4c7b2abdfe50345a663d2 Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sat, 18 Aug 2018 15:15:33 -0700 Subject: [PATCH 32/33] Susu kill and selfdestruct --- contracts/Susu.sol | 8 +++----- contracts/SusuParent.sol | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/contracts/Susu.sol b/contracts/Susu.sol index db40025..9e89795 100644 --- a/contracts/Susu.sol +++ b/contracts/Susu.sol @@ -10,7 +10,7 @@ contract Susu is Ownable { SusuDataStore public susuDataStore; uint8 constant public MAX_MEMBERS = 5; - string constant public version = '0.0.21'; + string constant public version = '0.0.32'; constructor(address _susuDataStoreAddress, address _newOwner) public { susuDataStore = SusuDataStore(_susuDataStoreAddress); @@ -113,10 +113,8 @@ contract Susu is Ownable { } // onlyOwner? - function transferValue(address _susuNew) external returns(bool){ -// TODO: selfdestruct(_upgradedSusu); -// _susuNew.transfer(address(this).balance); - return _susuNew.send(1); + function kill(address _newSusu) public payable { + selfdestruct(_newSusu); } } diff --git a/contracts/SusuParent.sol b/contracts/SusuParent.sol index 8bc3c2f..93c861c 100644 --- a/contracts/SusuParent.sol +++ b/contracts/SusuParent.sol @@ -34,7 +34,7 @@ contract SusuParent { address susuAddressOrig = registry.get(_key); Susu susu = Susu(susuAddressOrig); Susu susuNew = new Susu(susu.susuDataStore(), susu.owner()); - susu.transferValue(susuNew); + susu.kill(susuNew); registry.put(_key, susuNew); } From df68fe4b7f6835ce82bf0fa484066452d0f66c1b Mon Sep 17 00:00:00 2001 From: Shawn Cook Date: Sat, 18 Aug 2018 15:25:02 -0700 Subject: [PATCH 33/33] contract balance --- src/components/GroupInfo.js | 5 +++++ src/components/GroupPage.js | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/components/GroupInfo.js b/src/components/GroupInfo.js index f266b68..140fb61 100644 --- a/src/components/GroupInfo.js +++ b/src/components/GroupInfo.js @@ -24,6 +24,10 @@ class GroupInfo extends Component { + + + +
Contract Version: {this.props.contractVersion}
Contract Balance:{this.props.contractBalance}
); @@ -36,6 +40,7 @@ GroupInfo.defaultProps = { contribAmt: -1, contractAddress: 'contractAddress not set', contractVersion: 'contractVersion not set', + contractBalance: 0, }; export default GroupInfo diff --git a/src/components/GroupPage.js b/src/components/GroupPage.js index 265cf86..781a889 100644 --- a/src/components/GroupPage.js +++ b/src/components/GroupPage.js @@ -36,6 +36,7 @@ class GroupPage extends Component { memberAddrToPayNext:0, susuContractAddress: '', susuContractVersion: '', + susuContractBalance: 0, } } @@ -90,6 +91,12 @@ class GroupPage extends Component { this.setState({ partnerObjects: partnerObjects }); } + this.state.web3.eth.getBalance(this.state.susuContractAddress, (err, balanceBig)=>{ + let bigNumber = new BigNumber(balanceBig); + const susuContractBalance = _this.state.web3.fromWei(bigNumber, 'ether').toNumber(); + this.setState({susuContractBalance:susuContractBalance}); + }); + this.state.susuContract.groupName((err, groupName)=>{ this.setState({groupName:groupName}); }); @@ -145,12 +152,19 @@ class GroupPage extends Component { let isMemberToPayNext = this.state.memberAddrToPayNext===this.state.myAddress; let contractAddress = this.state.susuContractAddress; let contractVersion = this.state.susuContractVersion; + let contractBalance = this.state.susuContractBalance; return (
- + {this.createPartnerRows()}