From 75d426f0cc93decfc0e9d63e7be6d585e6381e2f Mon Sep 17 00:00:00 2001 From: bumi Date: Mon, 18 Jun 2018 15:28:50 +0200 Subject: [PATCH] Add Contribution contract The contribution contract implements an ERC721 interface which represents any contribution. The contributions are non-fungible (as opposed to the Kredits tokens) and can be not be transferred. The contract stores the history of any contribution. Contributions can be claimed which will issue the Kredits tokens to the contributor. This is an early implementation and misses some access control and probably more things. --- contracts/Contribution.sol | 92 +++++++++++++++++++++++++++ contracts/Token.sol | 2 +- migrations/1528988660_contribution.js | 13 ++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 contracts/Contribution.sol create mode 100644 migrations/1528988660_contribution.js diff --git a/contracts/Contribution.sol b/contracts/Contribution.sol new file mode 100644 index 0000000..5fa52b3 --- /dev/null +++ b/contracts/Contribution.sol @@ -0,0 +1,92 @@ +pragma solidity ^0.4.18; + +import "zeppelin-solidity/contracts/token/ERC721/ERC721Token.sol"; +import './upgradeable/Upgradeable.sol'; + +// ToDo: only load interfaces +import './Token.sol'; + +contract Contribution is Upgradeable, ERC721Token { + + struct Contribution { + address contributor; + uint amount; + bool issued; + uint proposalId; + string url; + uint256 claimAfterBlock; + bool exists; + } + string internal name_; + string internal symbol_; + + mapping(uint256 => string) contributionURIs; + + mapping(uint256 => address) contributionOwner; + mapping(address => uint256[]) ownedContributions; + + mapping(uint256 => Contribution) public contributions; + uint256 public contributionsCount; + + event ContributionAdded(uint256 id, address indexed contributor, uint256 amount); + + function tokenContract() view public returns (Token) { + return Token(registry.getProxyFor('Token')); + } + + function name() external view returns (string) { + return name_; + } + + function symbol() external view returns (string) { + return symbol_; + } + + function contributionURI(uint256 contributionId) public view returns (string) { + require(exists(contributionId)); + return contributions[contributionId].url; + } + + function ownerOf(uint256 contributionId) public view returns (address) { + require(exists(contributionId)); + return contributions[contributionId].contributor; + } + + function balanceOf(address contributor) public view returns (uint) { + return ownedContributions[contributor].length; + } + + function add(uint256 amount, uint256 proposalId, address contributor, uint256 blocksToWait, string url) public { + uint contributionId = contributionsCount + 1; + var c = contributions[contributionId]; + c.exists = true; + c.amount = amount; + c.issued = false; + c.proposalId = proposalId; + c.url = url; + c.contributor = contributor; + c.claimAfterBlock = block.number + blocksToWait; + + contributionsCount++; + + contributionOwner[contributionId] = contributor; + ownedContributions[contributor].push(contributionId); + + ContributionAdded(contributionId, contributor, amount); + } + + function claim(uint256 contributionId) public { + var c = contributions[contributionId]; + require(c.exists); + require(!c.issued); + require(block.number > c.claimAfterBlock); + tokenContract().mintFor(c.contributor, c.amount, contributionId); + c.issued = true; + } + + function exists(uint256 contributionId) view public returns (bool) { + return contributions[contributionId].exists; + } + + +} diff --git a/contracts/Token.sol b/contracts/Token.sol index 9d81a9f..61ca124 100644 --- a/contracts/Token.sol +++ b/contracts/Token.sol @@ -17,7 +17,7 @@ contract Token is Upgradeable, BasicToken { decimals = 18; } - function mintFor(address contributorAccount, uint256 amount, uint proposalId) onlyRegistryContractFor('Operator') public { + function mintFor(address contributorAccount, uint256 amount, uint proposalId) onlyRegistryContractFor('Contribution') public { totalSupply_ = totalSupply_.add(amount); balances[contributorAccount] = balances[contributorAccount].add(amount); diff --git a/migrations/1528988660_contribution.js b/migrations/1528988660_contribution.js new file mode 100644 index 0000000..f6cb6a9 --- /dev/null +++ b/migrations/1528988660_contribution.js @@ -0,0 +1,13 @@ +var Registry = artifacts.require('./Registry.sol'); +var Contribution = artifacts.require('./Contribution.sol'); + +module.exports = function(deployer) { + deployer.deploy(Contribution).then(function(contribution) { + console.log('Registry address: ', Registry.address); + console.log('Contribution address: ', Contribution.address); + Registry.deployed().then(function(registry) { + registry.addVersion('Contribution', Contribution.address); + registry.createProxy('Contribution', 1); + }); + }); +};