Guest User

Untitled

a guest
Jun 17th, 2018
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.41 KB | None | 0 0
  1. pragma solidity ^0.4.19;
  2.  
  3.  
  4. /**
  5. * @title safemath
  6. * @dev Math operations with safety checks that throw on error
  7. */
  8. library safemath {
  9.  
  10. /**
  11. * @dev Multiplies two numbers, throws on overflow.
  12. */
  13. function mul(uint256 a, uint256 b) internal pure returns (uint256) {
  14. if (a == 0) {
  15. return 0;
  16. }
  17. uint256 c = a * b;
  18. assert(c / a == b);
  19. return c;
  20. }
  21.  
  22. /**
  23. * @dev Integer division of two numbers, truncating the quotient.
  24. */
  25. function div(uint256 a, uint256 b) internal pure returns (uint256) {
  26. // assert(b > 0); // Solidity automatically throws when dividing by 0
  27. uint256 c = a / b;
  28. // assert(a == b * c + a % b); // There is no case in which this doesn't hold
  29. return c;
  30. }
  31.  
  32. /**
  33. * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  34. */
  35. function sub(uint256 a, uint256 b) internal pure returns (uint256) {
  36. assert(b <= a);
  37. return a - b;
  38. }
  39.  
  40. /**
  41. * @dev Adds two numbers, throws on overflow.
  42. */
  43. function add(uint256 a, uint256 b) internal pure returns (uint256) {
  44. uint256 c = a + b;
  45. assert(c >= a);
  46. return c;
  47. }
  48. }
  49.  
  50.  
  51.  
  52. /**
  53. * @title ownable
  54. * @dev The ownable contract has an owner address, and provides basic authorization control
  55. * functions, this simplifies the implementation of "user permissions".
  56. */
  57. contract ownable {
  58. address public owner;
  59.  
  60. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
  61.  
  62. /**
  63. * @dev The Ownable constructor sets the original `owner` of the contract to the sender
  64. * account.
  65. */
  66. constructor () public {
  67. owner = msg.sender;
  68. }
  69.  
  70.  
  71. /**
  72. * @dev Throws if called by any account other than the owner.
  73. */
  74. modifier onlyOwner() {
  75. require(msg.sender == owner);
  76. _;
  77. }
  78.  
  79.  
  80. /**
  81. * @dev Allows the current owner to transfer control of the contract to a newOwner.
  82. * @param newOwner The address to transfer ownership to.
  83. */
  84. function transferOwnership(address newOwner) public onlyOwner {
  85. require(newOwner != address(0));
  86. emit OwnershipTransferred(owner, newOwner);
  87. owner = newOwner;
  88. }
  89.  
  90. }
  91.  
  92.  
  93. contract erc721 {
  94. event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
  95. event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);
  96.  
  97. function balanceOf(address _owner) public view returns (uint256 _balance);
  98. function ownerOf(uint256 _tokenId) public view returns (address _owner);
  99. function transfer(address _to, uint256 _tokenId) public;
  100. function approve(address _to, uint256 _tokenId) public;
  101. function takeOwnership(uint256 _tokenId) public;
  102. }
  103.  
  104.  
  105. /**
  106. * @title KTaccess
  107. * @author Yihan -- CyberMiles
  108. * @dev This contract is for regulating the owners' addr.
  109. * Inherited by KTfactory.
  110. */
  111. contract KTaccess is ownable{
  112. address public o1Address;
  113. address public o2Address;
  114. address public o3Address;
  115.  
  116. modifier onlyOLevel() {
  117. require(
  118. msg.sender == o1Address ||
  119. msg.sender == o2Address ||
  120. msg.sender == o3Address ||
  121. msg.sender == owner
  122. );
  123. _;
  124. }
  125.  
  126. function setO1(address _newAddr) external onlyOLevel {
  127. require(_newAddr != address(0));
  128.  
  129. o1Address = _newAddr;
  130. }
  131.  
  132. function setO2(address _newAddr) external onlyOLevel {
  133. require(_newAddr != address(0));
  134.  
  135. o2Address = _newAddr;
  136. }
  137.  
  138. function setO3(address _newAddr) external onlyOLevel {
  139. require(_newAddr != address(0));
  140.  
  141. o3Address = _newAddr;
  142. }
  143.  
  144. }
  145.  
  146.  
  147. /**
  148. * @title KTfactory
  149. * @author Yihan -- CyberMiles
  150. * @dev This main contract for creating KTs.
  151. *
  152. * A KT, which is the token issued by Krypital, has the following properties:
  153. * an officail note that can be created only by the contract owner;
  154. * a personal note that can be modified by the current owner of the token;
  155. * a bool value indicating if the token is currently frozen by Krypital;
  156. * a gene which is a hashed value that changes when mutate (merge or decompose). This is for some future interesting apps :D
  157. * level, namely, the level of the token. Apparently higher is better :D
  158. * id, the key used to map to the associated KT.
  159. *
  160. */
  161.  
  162. contract KTfactory is ownable, KTaccess {
  163.  
  164. using safemath for uint256;
  165.  
  166. uint256 public maxId;
  167.  
  168. uint256 public initial_supply;
  169.  
  170. uint256 public curr_number;
  171.  
  172. event NewKT(string note, uint256 gene, uint256 level, uint256 tokenId);
  173. event UpdateNote(string newNote, uint256 tokenId);
  174. event PauseToken(uint256 tokenId);
  175. event UnpauseToken(uint256 tokenId);
  176.  
  177. struct KT {
  178. string officialNote;
  179. string personalNote;
  180. bool paused;
  181. uint256 gene;
  182. uint256 level;
  183. uint256 id;
  184. }
  185.  
  186. mapping (uint256 => KT) public KTs;
  187.  
  188. mapping (uint => address) public KTToOwner;
  189. mapping (address => uint) ownerKTCount;
  190.  
  191. modifier onlyOwnerOf(uint token_id) {
  192. require(msg.sender == KTToOwner[token_id]);
  193. _;
  194. }
  195.  
  196. modifier whenNotFrozen(uint token_id) {
  197. require(KTs[token_id].paused == false);
  198. _;
  199. }
  200.  
  201. modifier withinTotal() {
  202. require(curr_number<= initial_supply);
  203. _;
  204. }
  205.  
  206. modifier hasKT(uint token_id) {
  207. require(KTs[token_id].id != 0);
  208. _;
  209. }
  210.  
  211. /**
  212. * @dev The constructor. Sets the initial supply and some other global variables.
  213. * That's right, Krypital will only issue 2100 tokens in total. It also means the total number of KTs will not exceed this number!
  214. */
  215. constructor() public {
  216. initial_supply = 2100;
  217. maxId=0;
  218. curr_number=0;
  219. }
  220.  
  221. /**
  222. * @dev The creator of KTs. Only done by Krypital.
  223. * @param oNote - the official, special note left only by Krypital!
  224. */
  225. function _createKT(string oNote) public onlyOLevel withinTotal {
  226. uint thisId = maxId + 1;
  227. string pNote;
  228. uint256 thisGene = uint256(keccak256(oNote));
  229.  
  230. KT memory thisKT = KT({
  231. officialNote: oNote,
  232. personalNote: pNote,
  233. paused: false,
  234. gene: thisGene,
  235. level: 1,
  236. id: thisId
  237. });
  238.  
  239. KTs[thisId] = thisKT;
  240. maxId = maxId + 1;
  241. curr_number = curr_number + 1;
  242. KTToOwner[thisId] = msg.sender;
  243. ownerKTCount[msg.sender]++;
  244. emit NewKT(oNote, thisGene, 1, thisId);
  245. }
  246.  
  247. /**
  248. * @dev This method is for editing your personal note!
  249. * @param note - the note you want the old one to be replaced by
  250. * @param token_id - just token id
  251. */
  252. function _editPersonalNote(string note, uint token_id) public onlyOwnerOf(token_id) hasKT(token_id){
  253. KT storage currKT = KTs[token_id];
  254. currKT.personalNote = note;
  255. emit UpdateNote(note, token_id);
  256. }
  257.  
  258. /**
  259. * @dev Pauses a token, done by Krypital
  260. * When a token is paused by Krypital, the owner of the token can still update the personal note but the ownership cannot be transferred.
  261. * @param token_id - just token id
  262. */
  263. function pauseToken(uint token_id) public onlyOLevel hasKT(token_id){
  264. KT storage currKT = KTs[token_id];
  265. currKT.paused = true;
  266. emit PauseToken(token_id);
  267. }
  268.  
  269. /**
  270. * @dev Unpauses a token, done by Krypital
  271. * @param token_id - just token id
  272. */
  273. function unpauseToken(uint token_id) public onlyOLevel hasKT(token_id){
  274. KT storage currKT = KTs[token_id];
  275. currKT.paused = false;
  276. emit UnpauseToken(token_id);
  277. }
  278.  
  279. }
  280.  
  281.  
  282. /**
  283. * @title KT
  284. * @author Yihan -- CyberMiles
  285. * @dev This contract is the contract regulating the transfer, decomposition, merging mechanism amaong the tokens.
  286. */
  287. contract KT is KTfactory, erc721 {
  288.  
  289. using safemath for uint256;
  290.  
  291. mapping (uint => address) KTApprovals;
  292.  
  293. /**
  294. * @dev The modifer to regulate a KT's decomposability.
  295. * A level 1 KT is not decomposable.
  296. * @param token_id - simply token id.
  297. */
  298. modifier decomposeAllowed(uint token_id){
  299. require(KTs[token_id].level > 1);
  300. _;
  301. }
  302.  
  303. event Decompose(uint256 tokenId);
  304. event Merge(uint256 tokenId1, uint256 tokenId2);
  305.  
  306. /**
  307. * @dev This is for getting the ether back to the contract owner's account. Just in case someone generous sends the creator some ethers :P
  308. */
  309. function withdraw() external onlyOwner {
  310. owner.transfer(this.balance);
  311. }
  312.  
  313. /**
  314. * @dev For checking how many tokens you own.
  315. * @param _owner - the owner's addr
  316. */
  317. function balanceOf(address _owner) public view returns(uint256) {
  318. return ownerKTCount[_owner];
  319. }
  320.  
  321. /**
  322. * @dev For checking the owner of the given token.
  323. * @param _tokenId - just token id
  324. */
  325. function ownerOf(uint256 _tokenId) public view returns(address) {
  326. return KTToOwner[_tokenId];
  327. }
  328.  
  329. /**
  330. * @dev the private helper function for transfering ownership.
  331. * @param _from - current KT owner
  332. * @param _to - new KT owner
  333. * @param _tokenId - just token id
  334. */
  335. function _transfer(address _from, address _to, uint256 _tokenId) private hasKT(_tokenId) {
  336. ownerKTCount[_to] = ownerKTCount[_to].add(1);
  337. ownerKTCount[msg.sender] = ownerKTCount[msg.sender].sub(1);
  338. KTToOwner[_tokenId] = _to;
  339. emit Transfer(_from, _to, _tokenId);
  340. }
  341.  
  342. /**
  343. * @dev This method can be called if you are the token owner and you want to transfer the token to someone else.
  344. * @param _to - new KT owner
  345. * @param _tokenId - just token id
  346. */
  347. function transfer(address _to, uint256 _tokenId) public whenNotFrozen(_tokenId) onlyOwnerOf(_tokenId) hasKT(_tokenId){
  348. require(_to != address(0));
  349. _transfer(msg.sender, _to, _tokenId);
  350. }
  351.  
  352. /**
  353. * @dev An approved user can 'claim' a token of another user.
  354. * @param _to - new KT owner
  355. * @param _tokenId - just token id
  356. */
  357. function approve(address _to, uint256 _tokenId) public onlyOwnerOf(_tokenId) hasKT(_tokenId) {
  358. require(_to != address(0));
  359. KTApprovals[_tokenId] = _to;
  360. emit Approval(msg.sender, _to, _tokenId);
  361. }
  362.  
  363. /**
  364. * @dev The user to be approved must be approved by the current token holder.
  365. * @param _tokenId - just token id
  366. */
  367. function takeOwnership(uint256 _tokenId) public whenNotFrozen(_tokenId) hasKT(_tokenId){
  368. require(KTApprovals[_tokenId] == msg.sender);
  369. address owner = ownerOf(_tokenId);
  370. _transfer(owner, msg.sender, _tokenId);
  371. }
  372.  
  373. /**
  374. * @dev This method is for decomposing (or split) a token. Only can be done by token holder when token is not frozen.
  375. * Note: one of the tokens will take the original token's place, that is, the old ID will actually map to a new token!
  376. * Level down by 1!!! A level 1 token cannot be decomposed.
  377. * The genes of the two new born tokens will be both identical to the old token.
  378. * Notes of the two new tokens are identical to the original token.
  379. */
  380. function decompose(uint256 token_id) public whenNotFrozen(token_id) onlyOwnerOf(token_id) decomposeAllowed(token_id) hasKT(token_id) withinTotal{
  381. KT storage decomposed = KTs[token_id];
  382. decomposed.level = decomposed.level-1;
  383. decomposed.gene = decomposed.gene/2;
  384.  
  385. KT memory newKT = KT({
  386. officialNote: decomposed.officialNote,
  387. personalNote: decomposed.personalNote,
  388. paused: false,
  389. gene: decomposed.gene,
  390. level: decomposed.level,
  391. id: maxId.add(1)
  392. });
  393.  
  394. maxId=maxId.add(1);
  395. curr_number=curr_number.add(1);
  396. KTs[maxId]=newKT;
  397. KTToOwner[maxId]=KTToOwner[token_id];
  398. ownerKTCount[msg.sender]=ownerKTCount[msg.sender].add(1);
  399.  
  400. emit Decompose(token_id);
  401. }
  402.  
  403. /**
  404. * @dev This function is for merging 2 tokens. Only tokens with the same levels can be merge. A user can only choose to merge from his own tokens.
  405. * After merging, id and official note are merged to the previous token passed in the args.
  406. * NOTE that the notes associated with the second token will be wiped out! Use with your caution.
  407. * Level up by 1!!!
  408. * New gene = (gene1 + gene2) / 2
  409. * @param id1 - the ID to the 1st token, this ID will remain after merging.
  410. * @param id2 - the ID of the 2nd token, this ID will map to nothing after merging!!
  411. */
  412. function merge(uint256 id1, uint256 id2) public hasKT(id1) hasKT(id2) whenNotFrozen(id1) whenNotFrozen(id2) onlyOwnerOf(id1) onlyOwnerOf(id2){
  413. require(KTs[id1].level == KTs[id2].level);
  414. KT storage token1 = KTs[id1];
  415. token1.gene = (token1.gene + KTs[id2].gene) / 2;
  416. token1.level = (token1.level).add(1);
  417.  
  418. KT memory toDelete = KT ({
  419. officialNote: "",
  420. personalNote: "",
  421. paused: false,
  422. gene: 0,
  423. level: 0,
  424. id: 0
  425. });
  426.  
  427. KTs[id2] = toDelete;
  428. curr_number = curr_number.sub(1);
  429. KTToOwner[id2] = address(0);
  430. ownerKTCount[msg.sender] = ownerKTCount[msg.sender].sub(1);
  431.  
  432. emit Merge(id1, id2);
  433. }
  434.  
  435. }
Add Comment
Please, Sign In to add comment