From 8301514c6442d64ed2e59bbe86dc113eb513c3e9 Mon Sep 17 00:00:00 2001 From: bumi Date: Mon, 2 Apr 2018 16:53:25 +0200 Subject: [PATCH 1/3] Add script to send funds from the main account Helpful in development mode using ganache to fund another account usage: truffle exec scripts/send-funds.js
--- scripts/send-funds.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 scripts/send-funds.js diff --git a/scripts/send-funds.js b/scripts/send-funds.js new file mode 100644 index 0000000..e32287a --- /dev/null +++ b/scripts/send-funds.js @@ -0,0 +1,11 @@ + +module.exports = function(cb) { + let recipient = process.argv[4]; + if (!recipient) { + console.log('Please provide a recipient address'); + process.exit(); + } + let amount = parseInt(process.argv[5]) || 1; + console.log(recipient); + web3.eth.sendTransaction({to: recipient, value: web3.toWei(amount), from: web3.eth.accounts[0]}, console.log); +} -- 2.25.1 From f55e95c7ae7ee358ddbb3a392a52c9e3d0355075 Mon Sep 17 00:00:00 2001 From: bumi Date: Mon, 2 Apr 2018 18:09:12 +0200 Subject: [PATCH 2/3] Split IPFS hash for proposals to use bytes32 Uses the same method as in Contrbutors to store proposal hashes --- config/seeds.js | 6 +++--- contracts/Operator.sol | 18 +++++++++++------- contracts/Token.sol | 6 +++--- lib/abis/Operator.json | 2 +- lib/abis/Token.json | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/config/seeds.js b/config/seeds.js index a9803d2..47ce148 100644 --- a/config/seeds.js +++ b/config/seeds.js @@ -6,9 +6,9 @@ let contractCalls = { ['0xa502eb4021f3b9ab62f75b57a94e1cfbf81fd827', '0x9569ed44826286597982e40bbdff919c6b7752e29d13250efca452644e6b4b25', 18, 32, true] // QmYPu8zvtfDy18ZqHCviVxnKtxycw5UTJLJyk9oAEjWfnL ], addProposal: [ - [1, 23, 'QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs'], - [2, 42, 'QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs'], - [2, 100, 'QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs'] + [1, 23, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32], // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" + [2, 42, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32], // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" + [2, 100, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32] // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" ], vote: [ [1] diff --git a/contracts/Operator.sol b/contracts/Operator.sol index 20a82aa..8f85c5f 100644 --- a/contracts/Operator.sol +++ b/contracts/Operator.sol @@ -13,17 +13,19 @@ contract Operator is Upgradeable { uint votesNeeded; uint256 amount; bool executed; - string ipfsHash; + bytes32 ipfsHash; + uint8 hashFunction; + uint8 hashSize; mapping (address => bool) votes; bool exists; } Proposal[] public proposals; - event ProposalCreated(uint256 id, address creator, uint recipient, uint256 amount, string ipfsHash); + event ProposalCreated(uint256 id, address creator, uint recipient, uint256 amount); event ProposalVoted(uint256 id, address voter); event ProposalVoted(uint256 id, address voter, uint256 totalVotes); - event ProposalExecuted(uint256 id, uint recipient, uint256 amount, string ipfsHash); + event ProposalExecuted(uint256 id, uint recipient, uint256 amount); modifier coreOnly() { require(contributorsContract().addressIsCore(msg.sender)); @@ -72,7 +74,7 @@ contract Operator is Upgradeable { return proposals.length; } - function addProposal(uint _recipient, uint256 _amount, string _ipfsHash) public returns (uint256 proposalId) { + function addProposal(uint _recipient, uint256 _amount, bytes32 _ipfsHash, uint8 _hashFunction, uint8 _hashSize) public returns (uint256 proposalId) { require(contributorsContract().exists(_recipient)); proposalId = proposals.length; @@ -83,13 +85,15 @@ contract Operator is Upgradeable { recipientId: _recipient, amount: _amount, ipfsHash: _ipfsHash, + hashFunction: _hashFunction, + hashSize: _hashSize, votesCount: 0, votesNeeded: _votesNeeded, executed: false, exists: true }); proposals.push(p); - ProposalCreated(proposalId, msg.sender, p.recipientId, p.amount, p.ipfsHash); + ProposalCreated(proposalId, msg.sender, p.recipientId, p.amount); } function vote(uint256 _proposalId) public coreOnly returns (uint _pId, bool _executed) { @@ -117,9 +121,9 @@ contract Operator is Upgradeable { if (p.executed) { throw; } if (p.votesCount < p.votesNeeded) { throw; } address recipientAddress = contributorsContract().getContributorAddressById(p.recipientId); - tokenContract().mintFor(recipientAddress, p.amount, p.ipfsHash); + tokenContract().mintFor(recipientAddress, p.amount, proposalId); p.executed = true; - ProposalExecuted(proposalId, p.recipientId, p.amount, p.ipfsHash); + ProposalExecuted(proposalId, p.recipientId, p.amount); return true; } diff --git a/contracts/Token.sol b/contracts/Token.sol index d34c8ce..d892165 100644 --- a/contracts/Token.sol +++ b/contracts/Token.sol @@ -8,7 +8,7 @@ contract Token is Upgradeable, BasicToken { string public symbol; uint8 public decimals; - event LogMint(address indexed recipient, uint256 amount, string reference); + event LogMint(address indexed recipient, uint256 amount, uint256 proposalId); function initialize(address sender) public payable { require(msg.sender == address(registry)); @@ -17,11 +17,11 @@ contract Token is Upgradeable, BasicToken { decimals = 18; } - function mintFor(address _recipient, uint256 _amount, string _reference) onlyRegistryContractFor('Operator') public returns (bool success) { + function mintFor(address _recipient, uint256 _amount, uint _proposalId) onlyRegistryContractFor('Operator') public returns (bool success) { totalSupply_ = totalSupply_.add(_amount); balances[_recipient] = balances[_recipient].add(_amount); - LogMint(_recipient, _amount, _reference); + LogMint(_recipient, _amount, _proposalId); return true; } diff --git a/lib/abis/Operator.json b/lib/abis/Operator.json index 721a7f4..4d6415c 100644 --- a/lib/abis/Operator.json +++ b/lib/abis/Operator.json @@ -1 +1 @@ -[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"creator","type":"address"},{"name":"recipientId","type":"uint256"},{"name":"votesCount","type":"uint256"},{"name":"votesNeeded","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"executed","type":"bool"},{"name":"ipfsHash","type":"string"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"creator","type":"address"},{"indexed":false,"name":"recipient","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"ipfsHash","type":"string"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"voter","type":"address"}],"name":"ProposalVoted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"voter","type":"address"},{"indexed":false,"name":"totalVotes","type":"uint256"}],"name":"ProposalVoted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"recipient","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"ipfsHash","type":"string"}],"name":"ProposalExecuted","type":"event"},{"constant":true,"inputs":[],"name":"contributorsContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"coreContributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"},{"name":"_profileHash","type":"bytes32"},{"name":"_hashFunction","type":"uint8"},{"name":"_hashSize","type":"uint8"},{"name":"_isCore","type":"bool"}],"name":"addContributor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_profileHash","type":"bytes32"},{"name":"_hashFunction","type":"uint8"},{"name":"_hashSize","type":"uint8"}],"name":"updateContributorProfileHash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getContributor","outputs":[{"name":"account","type":"address"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"profileHash","type":"bytes32"},{"name":"isCore","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"proposalsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"uint256"},{"name":"_amount","type":"uint256"},{"name":"_ipfsHash","type":"string"}],"name":"addProposal","outputs":[{"name":"proposalId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_proposalId","type":"uint256"}],"name":"vote","outputs":[{"name":"_pId","type":"uint256"},{"name":"_executed","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_proposalId","type":"uint256"}],"name":"hasVotedFor","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}] \ No newline at end of file +[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"creator","type":"address"},{"name":"recipientId","type":"uint256"},{"name":"votesCount","type":"uint256"},{"name":"votesNeeded","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"executed","type":"bool"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"creator","type":"address"},{"indexed":false,"name":"recipient","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"voter","type":"address"}],"name":"ProposalVoted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"voter","type":"address"},{"indexed":false,"name":"totalVotes","type":"uint256"}],"name":"ProposalVoted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"recipient","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"constant":true,"inputs":[],"name":"contributorsContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"coreContributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"},{"name":"_profileHash","type":"bytes32"},{"name":"_hashFunction","type":"uint8"},{"name":"_hashSize","type":"uint8"},{"name":"_isCore","type":"bool"}],"name":"addContributor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_profileHash","type":"bytes32"},{"name":"_hashFunction","type":"uint8"},{"name":"_hashSize","type":"uint8"}],"name":"updateContributorProfileHash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getContributor","outputs":[{"name":"account","type":"address"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"profileHash","type":"bytes32"},{"name":"isCore","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"proposalsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"uint256"},{"name":"_amount","type":"uint256"},{"name":"_ipfsHash","type":"bytes32"},{"name":"_hashFunction","type":"uint8"},{"name":"_hashSize","type":"uint8"}],"name":"addProposal","outputs":[{"name":"proposalId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_proposalId","type":"uint256"}],"name":"vote","outputs":[{"name":"_pId","type":"uint256"},{"name":"_executed","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_proposalId","type":"uint256"}],"name":"hasVotedFor","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abis/Token.json b/lib/abis/Token.json index 0cc1924..64abf5b 100644 --- a/lib/abis/Token.json +++ b/lib/abis/Token.json @@ -1 +1 @@ -[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"reference","type":"string"}],"name":"LogMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_reference","type":"string"}],"name":"mintFor","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"proposalId","type":"uint256"}],"name":"LogMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_proposalId","type":"uint256"}],"name":"mintFor","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file -- 2.25.1 From d510bd4a037a0e8c0cc29a575c4c89ba59a279ee Mon Sep 17 00:00:00 2001 From: bumi Date: Mon, 2 Apr 2018 18:14:07 +0200 Subject: [PATCH 3/3] Use new proposal ipfs storage --- scripts/add-contributor.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/add-contributor.js b/scripts/add-contributor.js index 8d80a94..a930477 100644 --- a/scripts/add-contributor.js +++ b/scripts/add-contributor.js @@ -28,18 +28,21 @@ module.exports = function(callback) { proxess.exit(); } let ipfsHash = process.argv[5] || 'QmQyZJT9uikzDYTZLhhyVZ5ReZVCoMucYzyvDokDJsijhj'; - let multihash = getBytes32FromMultiash(ipfsHash); + let contributorMultihash = getBytes32FromMultiash(ipfsHash); let isCore = true; - operator.addContributor(contributorToAddAddress, multihash.digest, multihash.hashFunction, multihash.size, isCore).then((result) => { + operator.addContributor(contributorToAddAddress, contributorMultihash.digest, contributorMultihash.hashFunction, contributorMultihash.size, isCore).then((result) => { console.log('Contributor added, tx: ', result.tx); }); var contributorId = await contributors.getContributorIdByAddress(contributorToAddAddress); - operator.addProposal(contributorId, 23, "QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs").then((result) => { + let proposalMultihash = getBytes32FromMultiash('QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs'); + operator.addProposal(contributorId, 23, proposalMultihash.digest, proposalMultihash.hashFunction, proposalMultihash.size).then((result) => { console.log('Proposal added, tx: ', result.tx); }); var proposalId = await operator.proposalsCount(); - operator.vote(proposalId.toNumber()-1); + operator.vote(proposalId.toNumber()-1).then((result) => { + console.log('Voted for proposal', proposalId, result.tx); + }) }); } -- 2.25.1