Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
Menu
Open sidebar
Kevin F
decentralizedposts
Commits
d2f8682b
Commit
d2f8682b
authored
Jun 10, 2018
by
kevinflo
Browse files
initial public commit
parents
Changes
27
Expand all
Hide whitespace changes
Inline
Side-by-side
.gitignore
0 → 100755
View file @
d2f8682b
.idea
temp.sql
.vscode
notes.txt
node_modules
ethereum/build
secrets.json
wallet-key.json
scrap
.next
.DS_Store
\ No newline at end of file
.prettierrc
0 → 100644
View file @
d2f8682b
{
"singleQuote": true
}
LICENSE
0 → 100755
View file @
d2f8682b
MIT License
Copyright (c) 2018 Kevin Florenzano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
addresses.json
0 → 100644
View file @
d2f8682b
{
"DPOSTS"
:
{
"RINKEBY"
:
"0x33D430BC40141917F4389CC340dC3DEFA3df8526"
,
"RINKEBY2"
:
"0xA323C7A77c8778C96A2b89706331173fD306A0DC"
,
"RINKEBY3"
:
"0x6830D2D3F83295056A6600D45c3c6C72E0987478"
,
"RINKEBY4"
:
"0xcba065DCD2b7A8460bF3882d2586D75dE9E92E0f"
,
"RINKEBY5"
:
"0xC18A50F422a5e224E8A9aAAF21AE8C4489E3Be40"
,
"RINKEBY6"
:
"0xec42474bC2Fc05cdddEfA876d17737183FF4e4Fb"
}
}
ethereum/compile.js
0 → 100644
View file @
d2f8682b
const
path
=
require
(
'
path
'
);
const
solc
=
require
(
'
solc
'
);
const
fs
=
require
(
'
fs-extra
'
);
const
buildPath
=
path
.
resolve
(
__dirname
,
'
build
'
);
fs
.
removeSync
(
buildPath
);
const
dpostsPath
=
path
.
resolve
(
__dirname
,
'
contracts
'
,
'
Dposts.sol
'
);
const
source
=
fs
.
readFileSync
(
dpostsPath
,
'
utf8
'
);
const
output
=
solc
.
compile
(
source
,
1
).
contracts
;
fs
.
ensureDirSync
(
buildPath
);
for
(
let
contract
in
output
)
{
fs
.
outputJsonSync
(
path
.
resolve
(
buildPath
,
contract
.
replace
(
'
:
'
,
''
)
+
'
.json
'
),
output
[
contract
]
);
}
// module.exports = {
// Dposts: contracts[':Dposts'],
// Board: contracts[':Board']
// };
ethereum/contracts/dposts.sol
0 → 100755
View file @
d2f8682b
pragma
solidity
^
0.4
.
18
;
contract
Ownable
{
address
public
owner
;
function
Ownable
()
public
{
owner
=
msg
.
sender
;
}
modifier
onlyOwner
()
{
require
(
msg
.
sender
==
owner
);
_
;
}
function
transferOwnership
(
address
_newOwner
)
onlyOwner
public
{
owner
=
_newOwner
;
}
}
contract
Mortal
is
Ownable
{
function
terminate
()
public
onlyOwner
{
selfdestruct
(
msg
.
sender
);
}
}
contract
YearAware
{
uint
public
currentYear
;
// map of years to total collected pot for that year
// note that the keys will actually be years since epoch
mapping
(
uint
=>
uint
)
public
yearToTaxPot
;
function
determineBlockYear
()
public
view
returns
(
uint
)
{
return
block
.
timestamp
/
31536000
;
}
function
addPaidTaxToYearPot
(
uint
taxPaid
)
public
payable
{
yearToTaxPot
[
currentYear
]
+=
taxPaid
;
}
}
contract
Dposts
is
Mortal
,
YearAware
{
address
[]
public
boards
;
mapping
(
address
=>
uint
)
public
boardToBoardIndex
;
uint
public
lastCurrentTax
;
// fallback payable function
function
()
public
payable
{}
// all taxation is volunatary
// enough is an amount in ether the platform is capped at making per year
// it starts at 100 ether the first year
// and increases a little under 3% compound interest per year
// it is recalculated once per year at the start of the year
// and used to cap the tax pot for the duration of that year
// my dad had the idea for this capping when we were talking about how to fix some incentive problems
// and he read a book called enough and thought it would be cool to actually call the variable that
uint
enough
;
// this is just that in wei
uint
currentYearMaxTaxPot
;
function
createBoard
(
bytes32
name
,
bool
allowPosterEditing
,
bool
allowOwnerModeration
,
bool
allowBoardTipping
,
bool
allowTaxation
,
bool
allowPostTipping
,
bool
allowComments
,
bool
allowCommentTipping
,
uint
fee
)
public
returns
(
address
)
{
address
owner
=
msg
.
sender
;
address
board
=
new
Board
(
this
,
name
,
allowPosterEditing
,
allowOwnerModeration
,
allowBoardTipping
,
allowTaxation
,
allowPostTipping
,
allowComments
,
allowCommentTipping
,
fee
,
owner
);
uint
index
=
boards
.
push
(
board
)
-
1
;
boardToBoardIndex
[
board
]
=
index
;
emit
BoardCreated
(
name
,
index
,
board
);
return
board
;
}
event
BoardCreated
(
bytes32
name
,
uint
index
,
address
_board
);
function
getBoardsLength
()
public
view
returns
(
uint
)
{
return
boards
.
length
;
}
function
determineYearMaxTaxPot
(
uint
yearsSinceStart
)
private
pure
returns
(
uint
)
{
// This is a really inefficient and inaccurate implementation of compound interest
// Whatever, close enough. solidity makes some things confuzzling...
require
(
yearsSinceStart
>
0
);
uint
yearMaxTaxPot
=
100
;
for
(
uint
i
=
0
;
i
<
yearsSinceStart
;
i
++
)
{
yearMaxTaxPot
+=
(
yearMaxTaxPot
*
3
/
100
);
}
return
yearMaxTaxPot
;
}
function
determineTax
()
public
returns
(
uint
)
{
uint
blockYear
=
determineBlockYear
();
if
(
blockYear
!=
currentYear
)
{
currentYear
=
blockYear
;
enough
=
determineYearMaxTaxPot
(
blockYear
);
// I don't know why it won't let me use the ether keyword for this
currentYearMaxTaxPot
=
enough
*
1000000000000000000
;
}
// hard max single year amount is first person to pay tax that year
// current tax amount is single year max minus current pot divided
// by something that results in a reasonable max tip (first tipper that year)
lastCurrentTax
=
(
currentYearMaxTaxPot
-
yearToTaxPot
[
currentYear
])
/
400000
;
return
lastCurrentTax
;
}
function
getTaxPotForYear
(
uint
year
)
public
view
returns
(
uint
){
return
yearToTaxPot
[
year
];
}
function
getBoardNameAtIndex
(
uint
index
)
public
view
returns
(
bytes32
){
return
Board
(
boards
[
index
]).
name
();
}
function
getBoardUrlAtIndex
(
uint
index
)
public
view
returns
(
bytes32
){
return
Board
(
boards
[
index
]).
url
();
}
}
contract
Board
is
Mortal
,
YearAware
{
address
public
platform
;
bool
public
allowPosterEditing
;
bool
public
allowOwnerModeration
;
bool
public
allowBoardTipping
;
bool
public
allowTaxation
;
bool
public
allowPostTipping
;
bool
public
allowComments
;
bool
public
allowCommentTipping
;
bool
public
readOnly
;
uint
public
fee
;
bytes32
public
url
;
bytes32
public
name
;
Post
[]
public
posts
;
mapping
(
address
=>
uint
[])
public
posterToPostIndexes
;
Comment
[]
public
comments
;
mapping
(
uint
=>
uint
[])
public
postIndexToCommentIndexes
;
uint
public
totalPaidTax
;
// fallback payable function
function
()
public
payable
{}
function
Board
(
address
_platform
,
bytes32
_name
,
bool
_allowPosterEditing
,
bool
_allowOwnerModeration
,
bool
_allowBoardTipping
,
bool
_allowTaxation
,
bool
_allowPostTipping
,
bool
_allowComments
,
bool
_allowCommentTipping
,
uint
_fee
,
address
_owner
)
public
{
platform
=
_platform
;
name
=
_name
;
allowPosterEditing
=
_allowPosterEditing
;
allowOwnerModeration
=
_allowOwnerModeration
;
allowBoardTipping
=
_allowBoardTipping
;
allowTaxation
=
_allowTaxation
;
allowPostTipping
=
_allowPostTipping
;
allowComments
=
_allowComments
;
allowCommentTipping
=
_allowCommentTipping
;
fee
=
_fee
;
// this overrides the value from ownable
// because otherwise it's set to the dposts contract address
owner
=
_owner
;
}
struct
Post
{
uint
index
;
address
poster
;
bytes32
title
;
string
body
;
bytes32
link
;
uint
boardTip
;
uint
tax
;
uint
blockNumber
;
uint
createdAt
;
bool
visible
;
bool
hiddenByOwner
;
uint
tipTotal
;
}
event
PostCreated
(
uint
index
,
bytes32
title
,
string
body
,
bytes32
link
,
uint
boardTip
,
uint
tax
);
event
PostEdited
(
uint
index
,
bytes32
title
,
string
body
,
bytes32
link
,
bool
visible
);
struct
Comment
{
uint
index
;
uint
postIndex
;
address
poster
;
address
commenter
;
string
body
;
uint
tipTotal
;
uint
blockNumber
;
uint
createdAt
;
}
event
CommentCreated
(
uint
index
,
uint
postIndex
,
address
poster
,
address
commenter
,
string
body
);
// tipping always optional even when enabled at board level
function
createPost
(
bytes32
title
,
string
body
,
bytes32
link
,
uint
boardTip
,
uint
taxSubmitted
)
public
payable
returns
(
uint
)
{
require
(
readOnly
!=
true
);
if
(
!
allowBoardTipping
){
require
(
boardTip
==
0
);
}
uint
currentPlatformTax
;
if
(
taxSubmitted
>
0
){
currentPlatformTax
=
getCurrentPlatformTax
();
require
(
allowTaxation
);
require
(
taxSubmitted
>=
currentPlatformTax
);
}
require
(
msg
.
value
-
boardTip
-
currentPlatformTax
>=
fee
);
if
(
boardTip
>
0
)
{
require
(
msg
.
sender
!=
owner
);
owner
.
transfer
(
boardTip
);
}
if
(
fee
>
0
)
{
owner
.
transfer
(
fee
);
}
if
(
taxSubmitted
>
0
)
{
platform
.
transfer
(
currentPlatformTax
);
Dposts
(
platform
).
addPaidTaxToYearPot
(
currentPlatformTax
);
uint
blockYear
=
determineBlockYear
();
if
(
blockYear
!=
currentYear
)
{
currentYear
=
blockYear
;
addPaidTaxToYearPot
(
currentPlatformTax
);
addPaidTaxToTotalPaidTax
(
currentPlatformTax
);
}
Dposts
(
platform
).
determineTax
();
}
if
(
msg
.
value
>
0
){
// since the tax is a moving target it is quite likely the amount sent
// will be greater than the actual required tax by the time the platform gets it.
// because of this, createPost automatically kicks back the leftovers
uint
leftovers
=
msg
.
value
-
boardTip
-
currentPlatformTax
-
fee
;
if
(
leftovers
>
0
){
msg
.
sender
.
transfer
(
leftovers
);
}
}
uint
index
=
posts
.
length
;
Post
memory
newPost
=
Post
({
index
:
index
,
poster
:
msg
.
sender
,
title
:
title
,
body
:
body
,
link
:
link
,
boardTip
:
boardTip
,
tax
:
currentPlatformTax
,
blockNumber
:
block
.
number
,
createdAt
:
block
.
timestamp
,
visible
:
true
,
hiddenByOwner
:
false
,
tipTotal
:
0
});
posts
.
push
(
newPost
);
posterToPostIndexes
[
msg
.
sender
].
push
(
index
);
emit
PostCreated
(
index
,
title
,
body
,
link
,
boardTip
,
currentPlatformTax
);
return
index
;
}
function
addPaidTaxToTotalPaidTax
(
uint
paidTax
)
private
{
totalPaidTax
+=
paidTax
;
}
function
getPostCommentsLength
(
uint
postIndex
)
public
view
returns
(
uint
){
require
(
postIndex
<
posts
.
length
);
return
postIndexToCommentIndexes
[
postIndex
].
length
;
}
function
getCommentIndexByPostCommentsIndex
(
uint
postIndex
,
uint
postCommentsIndex
)
public
view
returns
(
uint
){
require
(
postIndex
<
posts
.
length
);
uint
[]
storage
postComments
=
postIndexToCommentIndexes
[
postIndex
];
require
(
postCommentsIndex
<
postComments
.
length
);
return
postComments
[
postCommentsIndex
];
}
function
createComment
(
uint
postIndex
,
string
body
)
public
returns
(
uint
)
{
require
(
readOnly
!=
true
);
uint
index
=
comments
.
length
;
require
(
postIndex
<
posts
.
length
);
Post
storage
_post
=
posts
[
index
];
Comment
memory
newComment
=
Comment
({
index
:
index
,
postIndex
:
postIndex
,
poster
:
_post
.
poster
,
commenter
:
msg
.
sender
,
body
:
body
,
tipTotal
:
0
,
blockNumber
:
block
.
number
,
createdAt
:
block
.
timestamp
});
comments
.
push
(
newComment
);
postIndexToCommentIndexes
[
postIndex
].
push
(
index
);
emit
CommentCreated
(
index
,
postIndex
,
_post
.
poster
,
msg
.
sender
,
body
);
return
index
;
}
modifier
onlyEditablePost
(
uint
index
){
require
(
allowPosterEditing
);
require
(
index
<
posts
.
length
);
Post
storage
_post
=
posts
[
index
];
require
(
_post
.
poster
==
msg
.
sender
);
_
;
}
function
editPostTitle
(
uint
index
,
bytes32
title
)
public
onlyEditablePost
(
index
)
{
require
(
readOnly
!=
true
);
Post
storage
_post
=
posts
[
index
];
require
(
msg
.
sender
==
_post
.
poster
);
_post
.
title
=
title
;
emitPostEditedEvent
(
_post
);
}
function
editPostBody
(
uint
index
,
string
body
)
public
onlyEditablePost
(
index
)
{
require
(
readOnly
!=
true
);
Post
storage
_post
=
posts
[
index
];
require
(
msg
.
sender
==
_post
.
poster
);
_post
.
body
=
body
;
emitPostEditedEvent
(
_post
);
}
function
editPostLink
(
uint
index
,
bytes32
link
)
public
onlyEditablePost
(
index
)
{
require
(
readOnly
!=
true
);
Post
storage
_post
=
posts
[
index
];
require
(
msg
.
sender
==
_post
.
poster
);
_post
.
link
=
link
;
emitPostEditedEvent
(
_post
);
}
function
editPostVisibility
(
uint
index
,
bool
visible
)
public
{
require
(
index
<
posts
.
length
);
Post
storage
_post
=
posts
[
index
];
bool
senderIsPoster
=
msg
.
sender
==
_post
.
poster
;
bool
senderIsOwner
=
msg
.
sender
==
owner
;
// Board owner having previously hid the post beats poster trying to show it again
require
((
senderIsPoster
&&
!
_post
.
hiddenByOwner
)
||
(
senderIsOwner
&&
allowOwnerModeration
));
_post
.
visible
=
visible
;
emitPostEditedEvent
(
_post
);
}
function
emitPostEditedEvent
(
Post
_post
)
internal
{
emit
PostEdited
(
_post
.
index
,
_post
.
title
,
_post
.
body
,
_post
.
link
,
_post
.
visible
);
}
function
getCurrentPlatformTax
()
public
returns
(
uint
){
return
Dposts
(
platform
).
determineTax
();
}
function
getPostsLength
()
public
view
returns
(
uint
)
{
return
posts
.
length
;
}
event
PosterTipped
(
uint
postIndex
,
uint
tip
,
uint
tipTotal
,
address
tipper
,
address
poster
);
event
CommenterTipped
(
uint
commentIndex
,
uint
tip
,
uint
tipTotal
,
address
tipper
,
address
poster
);
function
tipPoster
(
uint
postIndex
)
public
payable
returns
(
uint
)
{
require
(
msg
.
value
>
0
);
require
(
postIndex
<
posts
.
length
);
Post
storage
_post
=
posts
[
postIndex
];
require
(
msg
.
sender
!=
_post
.
poster
);
_post
.
poster
.
transfer
(
msg
.
value
);
_post
.
tipTotal
+=
msg
.
value
;
emit
PosterTipped
(
postIndex
,
msg
.
value
,
_post
.
tipTotal
,
msg
.
sender
,
_post
.
poster
);
return
_post
.
tipTotal
;
}
function
tipCommenter
(
uint
commentIndex
)
public
payable
returns
(
uint
)
{
require
(
msg
.
value
>
0
);
require
(
commentIndex
<
comments
.
length
);
Comment
storage
_comment
=
comments
[
commentIndex
];
require
(
msg
.
sender
!=
_comment
.
commenter
);
_comment
.
poster
.
transfer
(
msg
.
value
);
_comment
.
tipTotal
+=
msg
.
value
;
emit
CommenterTipped
(
commentIndex
,
msg
.
value
,
_comment
.
tipTotal
,
msg
.
sender
,
_comment
.
poster
);
return
_comment
.
tipTotal
;