Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented donate contract (with address registrar) #1

Merged
merged 15 commits into from
Dec 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ node_js:
- "8"

install:
- npm install truffle
- npm install

script:
- make build
- make ganache > ganache.log &
- sleep 5s
- make migrate
- make test

after_script:
- cat ganache.log
19 changes: 17 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
.PHONY: build test

build:
truffle compile
npx truffle compile

develop:
npx truffle develop

ganache:
npx ganache-cli --port 9545

stop-develop:
kill $$(ps -x | grep ganache | awk '{print $$1;}')

migrate:
npx truffle migrate

test:
truffle test
npx truffle test

clean:
rm -r build
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ Ethereum contracts used by Thankful.

[![Build Status](https://travis-ci.org/SuperuserLabs/thankful-contracts.svg?branch=master)](https://travis-ci.org/SuperuserLabs/thankful-contracts)

## How to develop

```sh
npm install
make build
make develop # start a development chain
make migrate # runs migrations
make test # run tests
```


For details about how to debug, see this guide: https://truffleframework.com/tutorials/debugging-a-smart-contract

Summary of the guide:

```sh
npx truffle debug <txid>
```


## Guides

Expand Down
30 changes: 30 additions & 0 deletions contracts/AddressRegistrar.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
pragma solidity ^0.4.24;

import './AddressRegistrar.sol';

contract AddressRegistrar {
// TODO: Make contract extend Ownable (for onlyOwner modifiers etc.)
// https://medium.com/codexprotocol/a-simple-framework-for-deploying-ownable-contracts-63ed4bd3c657
// The owner is the verifier
address public owner;

mapping(string => Creator) creators;

constructor() public {
owner = msg.sender;
}

struct Creator {
address addr;
}

// Associate an email with a wallet address
function associate(string _email, address _address) public {
require(msg.sender == owner);
creators[_email].addr = _address;
}

function getAddressByEmail(string _email) public constant returns (address) {
return creators[_email].addr;
}
}
61 changes: 61 additions & 0 deletions contracts/DonationHandler.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
pragma solidity ^0.4.24;

import './AddressRegistrar.sol';

contract DonationHandler {
address public owner;
AddressRegistrar public registrar;

mapping(string => PendingDonations) pending;

constructor(AddressRegistrar _registrar) public {
owner = msg.sender;
registrar = _registrar;
}

struct Donation {
address sender;
uint amount;
uint256 expires;
}

struct PendingDonations {
Donation[] donations;
uint n_pending;
uint refunded;
}

// Donate to a creator, add to pending if email has no connected address.
function donate(string _email, uint32 _expires_in) public payable {
require(msg.value > 0);
address _addr = registrar.getAddressByEmail(_email);
if(_addr != 0x0) {
_addr.transfer(msg.value);
} else {
pending[_email].donations.push(Donation(msg.sender, msg.value, now + _expires_in));
pending[_email].n_pending++;
}
}

// Refund pending transaction that has expired
function refund(string _email, uint32 _pending_idx) public {
require(now > pending[_email].donations[_pending_idx].expires);
delete pending[_email].donations[_pending_idx];
pending[_email].refunded++;
}

// Pay out last pending transaction for creator if email has an assigned address
function payOut(string _email) public returns (bool) {
address _addr = registrar.getAddressByEmail(_email);
require(_addr != 0x0 && pending[_email].n_pending > 0);
Donation storage d = pending[_email].donations[idx];
if(d.amount != 0x0) {
uint idx = pending[_email].n_pending - 1;
_addr.transfer(d.amount);
return true;
} else {
pending[_email].n_pending--;
return false;
}
}
}
4 changes: 2 additions & 2 deletions contracts/SupporterToken.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
pragma solidity ^0.4.24;

import 'openzeppelin-solidity/contracts/ownership/Ownable.sol';
// import 'openzeppelin-solidity/contracts/ownership/Ownable.sol';

contract SupporterToken is Ownable {
contract SupporterToken /*is Ownable*/ {
// Nothing here yet
// Will be a ERC721 token, see this issue: https://github.com/SuperuserLabs/thankful/issues/3
}
8 changes: 8 additions & 0 deletions migrations/2_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
let AddressRegistrar = artifacts.require("AddressRegistrar");
let DonationHandler = artifacts.require("DonationHandler");

module.exports = async function(deployer) {
deployer.deploy(AddressRegistrar).then(() => {
return deployer.deploy(DonationHandler, AddressRegistrar.address);
});
};
Loading