pragma solidity ^0.4.11; /* 【仮想通貨大喜利】 ・お題、ボケ、参加者をブロックチェーンで管理。 ・参加者は、お題を出したり、ボケたり、採点したりすることで仮想通貨の獲得を目指す。 ・ボケる人は、お題の作者にフィーを支払う。(= お題の作者はボケた人全員からフィーをもらえる。) ・採点する人は、おもしろいと思ったボケの作者にフィーを支払う。 ・採点することでお題を出す権利を得ることができる。(= 採点しないとお題を出すことができない) ・おもしろいボケをするよりも、みんなにボケたいと思わせるお題を出すことが、仮想通貨獲得の近道。 */ //uint32用オーバーフロー対策 library SafeMath { function mul(uint32 a, uint32 b) internal pure returns (uint32) { if (a == 0) { return 0; } uint32 c = a * b; assert(c / a == b); return c; } function div(uint32 a, uint32 b) internal pure returns (uint32) { // assert(b > 0); // Solidity automatically throws when dividing by 0 uint32 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function sub(uint32 a, uint32 b) internal pure returns (uint32) { assert(b <= a); return a - b; } function add(uint32 a, uint32 b) internal pure returns (uint32) { uint32 c = a + b; assert(c >= a); return c; } } //オーナー権限 contract Ownable{ address public owner; function Ownable() { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner); _; } function transferOwnership(address newOwner) onlyOwner { if (newOwner != address(0)) { owner = newOwner; } } } //大喜利コントラクト(ベース) contract OgiriBase is Ownable{ //uint32用オーバーフロー対策 using SafeMath for uint32; //各種フィー uint256 answerFee = 0.001 ether;//ボケる時に出題者に支払う uint256 scoreFee = 0.001 ether;//採点する時におもしろいボケの作者に支払う //イベント event eventQuestion(address author, uint256 id, string question);//お題を出した時 event eventAnswer(address author, uint256 id, string answer);//ボケた時 //ユーザー struct User{ string name;//ペンネーム uint32 canCreateQuestionCount;//お題を出せる回数(ボケを採点する毎に増える) } mapping (address => User) public users; //お題 struct Question{ uint64 time;//作成時間 string question;//お題 } Question[] questions; mapping (uint256 => address) public QuestionIndexToAuthor; //ボケ struct Answer{ uint256 questionId;//お題のID uint64 time;//作成時間 string answer;//ボケ uint32 score;//いいね数 } Answer[] answers; mapping (uint256 => address) public AnswerIndexToAuthor; //@dev 回答フィーを設定する //@param _price 金額 //@modifier onlyOwner 管理人のみ function setAnswerFee(uint256 _price) external onlyOwner{ answerFee = _price; } //@dev 採点フィーを設定する //@param _price 金額 //@modifier onlyOwner 管理人のみ function setScoreFee(uint256 _price) external onlyOwner{ scoreFee = _price; } //@dev ユーザー新規登録 //@param _name ペンネーム //@param _userAddress ユーザーアドレス function _createUser( string _name, address _address ) internal { users[_address] = User(_name,1); } //@dev お題を出す //@param _question お題 //@param _author 作者 //@return お題ID function _createQuestion( string _question, address _author ) internal returns (uint256) { require(users[_author].canCreateQuestionCount > 0);//出題権チェック uint256 newQuestionId = questions.push(Question(uint64(now),string(_question))) - 1; require(newQuestionId == uint256(uint32(newQuestionId))); QuestionIndexToAuthor[newQuestionId] = _author; users[_author].canCreateQuestionCount = users[_author].canCreateQuestionCount.sub(1);//出題権(回数)を1マイナス eventQuestion(_author,newQuestionId,_question); return newQuestionId; } //@dev ボケる //@param _questionId お題のID //@param _answer ボケ //@param _author 作者 //@return お題ID function _createAnswer( uint256 _questionId, string _answer, address _author ) internal returns(uint256) { uint256 newAnswerId = answers.push(Answer(_questionId ,uint64(now), _answer, 0)) - 1; require(newAnswerId == uint256(uint32(newAnswerId))); AnswerIndexToAuthor[newAnswerId] = _author; eventAnswer(_author,newAnswerId,_answer); return newAnswerId; } //@dev 採点する(おもしろいボケに「Good」ボタン) //@param _answerId ボケのID function _createScore( uint256 _answerId ) internal { answers[_answerId].score = answers[_answerId].score.add(1);//高評価を1プラス } } //大喜利コントラクト contract Ogiri is OgiriBase{ //@dev ユーザー新規作成 //@param _name ペンネーム function createUser( string _name ) external { require(msg.sender != address(0)); require(keccak256(users[msg.sender].name) == keccak256(""));//まだ新規登録していない場合のみ _createUser(_name,msg.sender); } //@dev お題を出す //@param _question お題 function createQuestion( string _question ) external { require(msg.sender != address(0)); _createQuestion(_question, msg.sender); } //@dev ボケる。回答フィーを出題者に支払う //@param _questionId お題のID //@param _answer ボケ function createAnswer( uint256 _questionId, string _answer ) external payable { require(msg.sender != address(0)); require(msg.value == answerFee); address questionAuthor = QuestionIndexToAuthor[_questionId]; require(questionAuthor != msg.sender);//出題者がボケることはできない _createAnswer(_questionId, _answer, msg.sender); questionAuthor.transfer(msg.value);//出題者に回答フィーを送金する } //@dev 採点する。採点フィーを作者に支払う //@param _answerId ボケのID function createScore( uint256 _answerId ) external payable { require(msg.sender != address(0)); require(msg.value == scoreFee); address answerAuthor = AnswerIndexToAuthor[_answerId]; require(answerAuthor != msg.sender);//自分のボケは採点できない _createScore(_answerId); users[msg.sender].canCreateQuestionCount = users[msg.sender].canCreateQuestionCount.add(1); answerAuthor.transfer(msg.value);//回答者に送金する } //以下view関数 //お題リスト(全部)取得 function getAllQuestions() public view returns(uint256[]){ uint256 questionCount = questions.length; if (questionCount == 0) { return new uint256[](0); } else { uint256[] memory result = new uint256[](questionCount); uint256 resultIndex = 0; uint256 questionId; for (questionId = 0; questionId < questionCount; questionId++) { if(QuestionIndexToAuthor[questionId] != address(0)){ result[resultIndex] = questionId; resultIndex ++; } } return result; } } //回答(指定お題)取得 function getAnswers(uint256 _questionId) public view returns(uint256[]){ uint256 answersCount = answers.length; if(answersCount == 0){ return new uint256[](0); }else{ uint256[] memory result = new uint256[](answersCount); uint256 resultIndex = 0; uint256 answerId; for (answerId = 0; answerId < answersCount; answerId++) { if(answers[answerId].questionId == _questionId){ result[resultIndex] = answerId; resultIndex ++; } } return result; } } }
0.4.11