Created
November 30, 2018 03:36
-
-
Save fromjyk/69afabdaf296bc8dffe9385c11da3fe4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.16; | |
contract owned { | |
address public owner; | |
function owned() public { | |
owner = msg.sender; | |
} | |
modifier onlyOwner { | |
require(msg.sender == owner); | |
_; | |
} | |
function transferOwnership(address newOwner) onlyOwner public { | |
owner = newOwner; | |
} | |
} | |
interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external; } | |
contract TokenERC20 { // 토큰의 공용 변수 | |
string public name; | |
string public symbol; | |
uint8 public decimals = 18; // 18 자릿수가 권장되는 기본값입니다, 변경하지 마십시오. | |
uint256 public totalSupply; | |
// 모든 잔액에 대한 배열을 만듭니다. | |
mapping (address => uint256) public balanceOf; | |
mapping (address => mapping (address => uint256)) public allowance; | |
// 이 이벤트는 블록체인에서 클라이언트에게 ‘이전’을 알려주는 공개 이벤트입니다. | |
event Transfer(address indexed from, address indexed to, uint256 value); | |
// 이 이벤트는 블록체인에서 클라이언트에게 ‘승인’을 알려주는 공개 이벤트입니다. | |
event Approval(address indexed _owner, address indexed _spender, uint256 _value); | |
// 이 이벤트는 클라이언트에게 ‘소각’을 알려주는 공개 이벤트입니다. | |
event Burn(address indexed from, uint256 value); | |
/* | |
* 생성자 함수 | |
* 컨트랙트 생성자에게 초기 공급 토큰과의 계약을 초기화합니다. | |
*/ | |
constrctor( | |
uint256 initialSupply, | |
string tokenName, | |
string tokenSymbol | |
) public { | |
totalSupply = initialSupply * 10 ** uint256(decimals);// 총 공급량을 십진수로 업데이트 합니다. | |
balanceOf[msg.sender] = totalSupply; // 작성자에게 모든 초기 토큰을 제공합니다. | |
name = tokenName; // 표시 목적으로 토큰의 이름을 설정합니다. | |
symbol = tokenSymbol; // 표시 목적으로 토큰의 기호를 설정합니다. | |
} | |
/* | |
* 내부 전송, 오직 이 계약에서만 호출할 수 있습니다. | |
*/ | |
function _transfer(address _from, address _to, uint _value) internal { | |
// 0x0 주소로 전송을 방지합니다. 사용하게 되면 소각을 진행합니다. | |
require(_to != 0x0); | |
// 보낸 사람의 자산이 충분한지 확인합니다. | |
require(balanceOf[_from] >= _value); | |
// 자산보다 넘게 보내는지 확인합니다. | |
require(balanceOf[_to] + _value > balanceOf[_to]); | |
// 향후 주장을 위해 이 정보를 저장합니다. | |
uint previousBalances = balanceOf[_from] + balanceOf[_to]; | |
// 발신자에게서 자산을 뺍니다. | |
balanceOf[_from] -= _value; | |
// 수신자에게 같은 양의 자산을 더합니다. | |
balanceOf[_to] += _value; | |
emit Transfer(_from, _to, _value); | |
// 주장들은 정적 분석을 사용하여 코드에서 버그를 찾습니다. 이것을 빼놓지 마십시오. | |
assert(balanceOf[_from] + balanceOf[_to] == previousBalances); | |
} | |
/* | |
* 토큰 전송 | |
* 계정에서 `_to`에 `_value` 토큰을 전송합니다. | |
* @param _to 수신자의 주소 | |
* @param _value 보낼 금액 | |
*/ | |
function transfer(address _to, uint256 _value) public returns (bool success) { | |
_transfer(msg.sender, _to, _value); | |
return true; | |
} | |
/* | |
* 다른 주소로 토큰 전송 | |
* `_from`을 대신하여 `_value` 토큰을 `_to` 에 전송합니다. | |
* @param _from 보낸 사람의 주소 | |
* @param _to 받는 사람의 주소 | |
* @param _value 보낼 금액 | |
*/ | |
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { | |
require(_value <= allowance[_from][msg.sender]); // 수량을 확인합니다. | |
allowance[_from][msg.sender] -= _value; | |
_transfer(_from, _to, _value); | |
return true; | |
} | |
/* | |
* 다른 주소에 대한 허용 설정 | |
* `_spender`가 우리를 대신하여 `_value`토큰을 사용할 수 있도록 허용합니다. | |
* @param _spender 지출할 수 있는 승인된 주소 | |
* @param _value 보낼 수 있는 총 수량 | |
*/ | |
function approve(address _spender, uint256 _value) public | |
returns (bool success) { | |
allowance[msg.sender][_spender] = _value; | |
emit Approval(msg.sender, _spender, _value); | |
return true; | |
} | |
/* | |
* 다른 주소에 대한 허용치 설정 및 알림 | |
* `_spender`가 우리를 대신하여 `_value` 토큰 이상의 토큰을 소비할 수 있게 한 다음, 그것에 대한 컨트랙트를 테스트 합니다. | |
* @param _spender 지출 권한이 있는 주소 | |
* @param _value 지출할 수 있는 최대 금액 | |
* @param _extraData 승인 된 컨트랙트에 보낼 추가 정보 | |
*/ | |
function approveAndCall(address _spender, uint256 _value, bytes _extraData) | |
public | |
returns (bool success) { | |
tokenRecipient spender = tokenRecipient(_spender); | |
if (approve(_spender, _value)) { | |
spender.receiveApproval(msg.sender, _value, this, _extraData); | |
return true; | |
} | |
} | |
/* | |
* 토큰 소각 | |
* 시스템에서 `_value`토큰을 되돌릴 수 없습니다. | |
* @param _value 소각할 양 | |
*/ | |
function burn(uint256 _value) public returns (bool success) { | |
require(balanceOf[msg.sender] >= _value); // 보낸 사람이 자산이 충분한지 확인합니다. | |
balanceOf[msg.sender] -= _value; // 발신자의 자산에서 뺍니다. | |
totalSupply -= _value; // 총 공급량을 업데이트합니다. | |
emit Burn(msg.sender, _value); | |
return true; | |
} | |
/* | |
* 다른 계정에서 토큰 소각 | |
* `_from`을 대신하여 시스템에서 `_value` 토큰을 비가역적으로 소각합니다. | |
* @param _from 보내는 사람의 주소 | |
* @param _value 소각할 총 양 | |
*/ | |
function burnFrom(address _from, uint256 _value) public returns (bool success) { | |
require(balanceOf[_from] >= _value); // 목표한 잔액이 충분한지 확인합니다. | |
require(_value <= allowance[_from][msg.sender]); // 허가 여부를 확인합니다. | |
balanceOf[_from] -= _value; // 목표 잔액에서 차감 | |
allowance[_from][msg.sender] -= _value; // 보낸사람의 허가로부터 차감합니다. | |
totalSupply -= _value; // 총 공급량을 업데이트합니다. | |
emit Burn(_from, _value); | |
return true; | |
} | |
} | |
/******************************************/ | |
/* 향상된 토큰 상태 */ | |
/******************************************/ | |
contract MyAdvancedToken is owned, TokenERC20 { | |
uint256 public sellPrice; | |
uint256 public buyPrice; | |
mapping (address => bool) public frozenAccount; | |
/* 이 이벤트는 블록체인에서 클라이언트에게 ‘잠금’을 알려주는 공개 이벤트입니다. */ | |
event FrozenFunds(address target, bool frozen); | |
/* 컨트랙트 작성자에게 초기 공급 토큰과의 계약을 초기화합니다. */ | |
function MyAdvancedToken( | |
uint256 initialSupply, | |
string tokenName, | |
string tokenSymbol | |
) TokenERC20(initialSupply, tokenName, tokenSymbol) public {} | |
/* 내부 전송, 이 계약에 의해서만 호출 될 수 있습니다. */ | |
function _transfer(address _from, address _to, uint _value) internal { | |
require (_to != 0x0); // 0x0 주소로의 전송을 방지하십시오. 사용하면 소각 됩니다. | |
require (balanceOf[_from] >= _value); // 보낸 사람의 자산이 충분히 있는지 확인합니다. | |
require (balanceOf[_to] + _value >= balanceOf[_to]); // 오버플로우를 확인합니다. | |
require(!frozenAccount[_from]); // 발신자의 계정이 잠금되어 있는지 확인합니다. | |
require(!frozenAccount[_to]); // 수신자의 계정이 잠금되어 있는지 확인합니다. | |
balanceOf[_from] -= _value; // 발신자의 자산에서 차감합니다. | |
balanceOf[_to] += _value; // 수신자에게 같을 양을 추가합니다. | |
emit Transfer(_from, _to, _value); | |
} | |
/// @notice 새로운 토큰을 찍어낼 수 있으며 `target` 에 전송합니다. | |
/// @param 토큰을 받게 되는 타겟 주소 | |
/// @param 찍어낸 토큰의 양을 받습니다. | |
function mintToken(address target, uint256 mintedAmount) onlyOwner public { | |
balanceOf[target] += mintedAmount; | |
totalSupply += mintedAmount; | |
emit Transfer(0, this, mintedAmount); | |
emit Transfer(this, target, mintedAmount); | |
} | |
/// @notice 동결계좌의 방지 | `target`이 토큰을 보내고 받는것을 허용합니다. | |
/// @param 동결 대상의 주소 | |
/// @param 어느쪽이든 동결할 수있고 하지 않을 수 있다. | |
function freezeAccount(address target, bool freeze) onlyOwner public { | |
frozenAccount[target] = freeze; | |
emit FrozenFunds(target, freeze); | |
} | |
/// @notice 클라이언트가 `newBuyPrice`에 대한 토큰을 구입하고 `newSellPrice`에 대한 토큰을 판매하도록 허용합니다. | |
/// @param newSellPrice 컨트랙트에 판매 할 수 있는 가격 | |
/// @param newBuyPrice 컨트랙트로 부터 팔 수 있는 가격 | |
function setPrices(uint256 newSellPrice, uint256 newBuyPrice) onlyOwner public { | |
sellPrice = newSellPrice; | |
buyPrice = newBuyPrice; | |
} | |
/// @notice 이더리움을 보내서 컨트랙터에서 토큰을 구입합니다. | |
function buy() payable public { | |
uint amount = msg.value / buyPrice; // 수량을 계산합니다. | |
_transfer(this, msg.sender, amount); // 전송을 발생시킵니다. | |
} | |
/// @notice 컨트랙트에 `amount`만큼의 토큰 판매 | |
/// @param ‘amount’ 매매할 토큰의 금액 | |
function sell(uint256 amount) public { | |
address myAddress = this; | |
require(myAddress.balance >= amount * sellPrice); // 컨트랙트에 충분한 이더리움이 있는지 확인합니다. | |
_transfer(msg.sender, this, amount); // 전송을 발생시킵니다. | |
msg.sender.transfer(amount * sellPrice); // 이더리움을 판매자에게 보냅니다. 재귀공격을 피하려면 이 작업을 마지막으로 수행하는 것이 중요합니다. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment