develop custom_top_html:no
default debug random = 0 / type = READ / detected = READ
30분만에 ICO하기
 
안녕하세요. 오늘은 조금 자극적인 제목을 가지고 와봤습니다. 요즘 ICO 많이들 참여하시고,  직접 하시는 분들도 많이 계신데요. ICO에 필요한 토큰을 단 30분 만에 발행하는 방법을 소개해볼까 합니다.
 
준비물은 단 한 가지. mist 지갑입니다. 이 mist 지갑에는 스마트 컨트랙을 발행하는 기능이 있는데요. 여기에 아래와 같이 ERC20 표준에 해당하는 코드를 넣고 발행하기만 하면, 순식간에 토큰 하나가 뚝딱 만들어집니다.
 
코드 예시 : 
 
pragma solidity ^0.4.16;
interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public; }
contract TokenERC20 {
    // Public variables of the token
    string public name;
    string public symbol;
    uint8 public decimals = 18;
    // 18 decimals is the strongly suggested default, avoid changing it
    uint256 public totalSupply;
    // This creates an array with all balances
    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint256)) public allowance;
    // This generates a public event on the blockchain that will notify clients
    event Transfer(address indexed from, address indexed to, uint256 value);
    // This notifies clients about the amount burnt
    event Burn(address indexed from, uint256 value);
    /**
     * Constructor function
     *
     * Initializes contract with initial supply tokens to the creator of the contract
     */
    function TokenERC20(
        uint256 initialSupply,
        string tokenName,
        string tokenSymbol
    ) public {
        totalSupply = initialSupply * 10 ** uint256(decimals);  // Update total supply with the decimal amount
        balanceOf[msg.sender] = totalSupply;                // Give the creator all initial tokens
        name = tokenName;                                   // Set the name for display purposes
        symbol = tokenSymbol;                               // Set the symbol for display purposes
    }
    /**
     * Internal transfer, only can be called by this contract
     */
    function _transfer(address _from, address _to, uint _value) internal {
        // Prevent transfer to 0x0 address. Use burn() instead
        require(_to != 0x0);
        // Check if the sender has enough
        require(balanceOf[_from] >= _value);
        // Check for overflows
        require(balanceOf[_to] + _value > balanceOf[_to]);
        // Save this for an assertion in the future
        uint previousBalances = balanceOf[_from] + balanceOf[_to];
        // Subtract from the sender
        balanceOf[_from] -= _value;
        // Add the same to the recipient
        balanceOf[_to] += _value;
        Transfer(_from, _to, _value);
        // Asserts are used to use static analysis to find bugs in your code. They should never fail
        assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
    }
    /**
     * Transfer tokens
     *
     * Send `_value` tokens to `_to` from your account
     *
     * @param _to The address of the recipient
     * @param _value the amount to send
     */
    function transfer(address _to, uint256 _value) public {
        _transfer(msg.sender, _to, _value);
    }
    /**
     * Transfer tokens from other address
     *
     * Send `_value` tokens to `_to` on behalf of `_from`
     *
     * @param _from The address of the sender
     * @param _to The address of the recipient
     * @param _value the amount to send
     */
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        require(_value <= allowance[_from][msg.sender]);     // Check allowance
        allowance[_from][msg.sender] -= _value;
        _transfer(_from, _to, _value);
        return true;
    }
    /**
     * Set allowance for other address
     *
     * Allows `_spender` to spend no more than `_value` tokens on your behalf
     *
     * @param _spender The address authorized to spend
     * @param _value the max amount they can spend
     */
    function approve(address _spender, uint256 _value) public
        returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        return true;
    }
    /**
     * Set allowance for other address and notify
     *
     * Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it
     *
     * @param _spender The address authorized to spend
     * @param _value the max amount they can spend
     * @param _extraData some extra information to send to the approved contract
     */
    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;
        }
    }
    /**
     * Destroy tokens
     *
     * Remove `_value` tokens from the system irreversibly
     *
     * @param _value the amount of money to burn
     */
    function burn(uint256 _value) public returns (bool success) {
        require(balanceOf[msg.sender] >= _value);   // Check if the sender has enough
        balanceOf[msg.sender] -= _value;            // Subtract from the sender
        totalSupply -= _value;                      // Updates totalSupply
        Burn(msg.sender, _value);
        return true;
    }
    /**
     * Destroy tokens from other account
     *
     * Remove `_value` tokens from the system irreversibly on behalf of `_from`.
     *
     * @param _from the address of the sender
     * @param _value the amount of money to burn
     */
    function burnFrom(address _from, uint256 _value) public returns (bool success) {
        require(balanceOf[_from] >= _value);                // Check if the targeted balance is enough
        require(_value <= allowance[_from][msg.sender]);    // Check allowance
        balanceOf[_from] -= _value;                         // Subtract from the targeted balance
        allowance[_from][msg.sender] -= _value;             // Subtract from the sender's allowance
        totalSupply -= _value;                              // Update totalSupply
        Burn(_from, _value);
        return true;
    }
}
 
 
 
KakaoTalk_20180218_203831395.png

 

 
 
어때요 정말 쉽지 않나요? SUPERTOKEN이라는 이름을 가진 토큰이 하나 만들어졌습니다. 이 과정에서 가장 어려운 일은 mist 지갑을 준비하는 일입니다. mist 지갑은 이더리움 네트워크와 싱크를 맞추기 위해서 상당한 시간이 소요됩니다. 적어도 하루는 잡아야 하고요. PC 사양에 따라서 오래 걸릴 경우에는 일주일 이상 소요될 수 있습니다.
 
여기서 우리는 몇 가지 시사점을 얻을 수 있습니다.
 
 
1. 생각보다 많은 ICO들이 이런 허접한 컨트랙을 가지고 ICO를 진행합니다. 컨트랙이 공개된 몇몇 해외 유명 ICO들과 국내 ICO들을 뒤져보면, 30분 만에 찍어낸 수준으로 토큰을 발행한 곳들이 많습니다. ICO에 거액이 투자되는데도 사람들은 내용을 모르고 너무 쉽게 쉽게들 투자하죠. 
 
2. 그렇지만 토큰 발행에는 그닥 많은 기능이 필요하지 않은 게 사실이기도 합니다. 요즘 ICO에 필수라고 여겨지는 KYC나 토큰 전송 기능, 아무나 컨트랙에 손대지 못하게 하는 권한 분배, 최근 NEM 해킹 사태처럼 비상 사태가 발생했을 때 대처할 수 있는 기능들, DApp 개발 후에 포크를 위한 포크 기능 정도면 충분합니다. 그러나 이정도도 없이 30분 완성 컨트랙으로 적당히 ICO를 때우려는 사람들이 있는 것도 사실이죠.
 
3. ICO는 끝이 아니라 시작입니다. 많은 ICO 주최자들과 심지어는 참여자들까지도 간과하고 있는 사실이 바로 ICO는 시작에 불과하다는 점입니다. 주최자들은 물론이고 주최자들을 감시해야 할 참여자들까지도 투더문을 외치는 모습이 바람직하다고만 볼 수는 없습니다. ICO는 DApp을 만들고 사람들이 원하는 서비스를 제공하기 위해 시작하는 것인데, ICO로 거액을 모았다고 해서 그것이 끝인 것처럼 행동해서는 안된다는 것이죠.
 
 
마치며, 첫 ICO를 준비하는 개발자들에게 도움이 될만한 것들을 적어봅니다. 
 
 
미니미 토큰은 포크를 하기 위해 적합한 라이브러리입니다. 소스들을 뜯어보면 알겠지만, 정말 손쉽게 다음 버전의 토큰을 만들어낼 수 있습니다. 토큰 배분 후에 개발을 진행하고, 개발 후에 새로운 기능을 추가해서 토큰 홀더들에게 새 토큰을 발행하는 것까지 이미 완성되어 있습니다. 실제 사용할 때는 약간 수정할 부분들이 있지만, 사용하기에 큰 무리가 없습니다.
 
 
ICO Wizard는 ICO를 준비하는 사람들을 위해서 만들어졌고, 원하는 정보들을 입력하면 필요한 코드를 생성해줍니다. 그대로 사용하기는 무리가 있지만 베이스가 없는 상황에서 구조를 설계하는 것엔 많은 도움이 됩니다. 

 

 

 

-------------------------------------

꼬리말

* 게시글 내용 삭제레벨 강등

* 질문은 각 주제별 게시판에.

 

비트코인 암호화화폐 커뮤니티 땡글~ 땡글~

-------------------------------------

269

파이리님의 서명

Blockchainnovation

ERC20 토큰 개발, 암호화폐 지갑 개발, 스마트 컨트랙 개발

댓글 28
  • ?
    이렇게 전문적으로 아는분들이 얼마나 될까요?
    그냥 돈 된다고 하면 불나방처럼 뛰어들어가는거죠
  • 좋은 정보 감사합니다!
  • 일반분들이 이런 내용을 알아야 할 텐데요.. 삐까뻔쩍한 홈피만 보고 우르르...대박의 꿈만 쫒다보니.
  • esc는 2번 항목 다 갖추고있는지 궁금하네요?
  • @maxsin
    ESC는 이더리움 소스를 이용한 블록체인이고 위 설명은 이더리움 위에 ERC20 토큰입니다.

    범주가 다릅니다.
  • ?
    잘 읽었습니다. 감사합니다.~~
  • ?
    좋은글 잘읽엇습니다... 혹시 코인하나 뚝딱 만들어 주실수 잇는지요?
    쪽지 주시면 감사하겟습니다.
  • @비밀번호
    제가 진행하고 있는 프로젝트들이 있어서 어려울 것 같습니다. 죄송합니다 (_ _)
  • Great~
  • ?
    좋은글 감사합니다
  • ?
    좋은 자료 감사합니다! 암호화폐의 가장 큰 내부의 적은 무한히 증식하는 스캠코인들이 아닐까합니다. 코인에도 저작권 개념이 있었다면 좋았을텐데요. 카피 코인들은 법률적으로는 아니더라도 시장에서 냉정하게 밴시키면 좋겠습니다.
  • ?
    @OldBoy
    대부분 erc20 표준 코드에 이름만 바꾸는게 대부분이라 저작권, 카피 개념 적용이 불가능합니다.
  • ?
    감사합니다. 이런식으로 쉽게 만드는 스캠들이 발생하는거군요
  • 토큰의 위험성이죠
  • ?
    이런 자료들 볼수있는 자료실 카테고리 운영된다면,,,정망 감사할듯,,합니다,
  • ?
    좋아요...~~
  • ?
    이런 글에 좋아요를 주지 않으면 어떤 글에 줘야 할까요..ㅋ 정말 좋은 글입니다.
  • ?
    좋은 글 감사합니다.
  • 이 sentence들이 무슨 언어 인가요?
    따라서 쭉 읽어 보는데 모르는 단어들이 있네요 @param

    1억개의 SPT코인 내용은 알겠는데요

  • 좋은 정보입니다.
    깃허브에 보면 토큰만드는 오픈소스가 많이 올라와 있습니다. 코딩을 스페셜하게 하시는 분들은 직접 코인을 발행하고 지갑도 만들고 노드도 돌리면서 채굴까지 1인이 플렛폼을 다 꾸미기도합니다. 그런 코인들 많습니다.
  • ?
    대부분 위처럼 erc20 표준을 따르는 토큰인데, 저 소스 코드를 개선한다고 해서 NEM 사태를 막을 수 있는 방법이 있나요? 만약에 토큰 창조자가 일종의 동결기능을 만들면 중앙 통제가 일어나는것인데.. 글쓴이 님이 생각하시는 비상상태 대비 코드가 무엇인지 알려주셨으면 합니다
  • ?
    좋은 정보 정말 감사합니다.
  • ?
    올려주신 글 보면서 공부 해보겠습니다.
  • ?
    난 언제 이런 전문가가 될 수 있을까요 ㅎㅎㅎ 감사히 잘 읽었습니다.
  • ?
    혹시요 이더리움 네트워크 와 싱크할때요 소량의 이더리움이 필요한가요??
  • ?
    Rinkeby에서 해봤는데 안되네요...혹시 메인넷에서만 되는건가요?
  • @로텔
    pragma solidity ^0.4.16;
    interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external; }
    contract TokenERC20 {
    // Public variables of the token
    string public name;
    string public symbol;
    uint8 public decimals = 18;
    // 18 decimals is the strongly suggested default, avoid changing it
    uint256 public totalSupply;
    // This creates an array with all balances
    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint256)) public allowance;
    // This generates a public event on the blockchain that will notify clients
    event Transfer(address indexed from, address indexed to, uint256 value);
    // This notifies clients about the amount burnt
    event Burn(address indexed from, uint256 value);
    /**
    * Constructor function
    *
    * Initializes contract with initial supply tokens to the creator of the contract
    */
    function TokenERC20(
    uint256 initialSupply,
    string tokenName,
    string tokenSymbol
    ) public {
    totalSupply = initialSupply * 10 ** uint256(decimals); // Update total supply with the decimal amount
    balanceOf[msg.sender] = totalSupply; // Give the creator all initial tokens
    name = tokenName; // Set the name for display purposes
    symbol = tokenSymbol; // Set the symbol for display purposes
    }
    /**
    * Internal transfer, only can be called by this contract
    */
    function _transfer(address _from, address _to, uint _value) internal {
    // Prevent transfer to 0x0 address. Use burn() instead
    require(_to != 0x0);
    // Check if the sender has enough
    require(balanceOf[_from] >= _value);
    // Check for overflows
    require(balanceOf[_to] + _value > balanceOf[_to]);
    // Save this for an assertion in the future
    uint previousBalances = balanceOf[_from] + balanceOf[_to];
    // Subtract from the sender
    balanceOf[_from] -= _value;
    // Add the same to the recipient
    balanceOf[_to] += _value;
    emit Transfer(_from, _to, _value);
    // Asserts are used to use static analysis to find bugs in your code. They should never fail
    assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
    }
    /**
    * Transfer tokens
    *
    * Send `_value` tokens to `_to` from your account
    *
    * @param _to The address of the recipient
    * @param _value the amount to send
    */
    function transfer(address _to, uint256 _value) public {
    _transfer(msg.sender, _to, _value);
    }
    /**
    * Transfer tokens from other address
    *
    * Send `_value` tokens to `_to` on behalf of `_from`
    *
    * @param _from The address of the sender
    * @param _to The address of the recipient
    * @param _value the amount to send
    */
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
    require(_value <= allowance[_from][msg.sender]); // Check allowance
    allowance[_from][msg.sender] -= _value;
    _transfer(_from, _to, _value);
    return true;
    }
    /**
    * Set allowance for other address
    *
    * Allows `_spender` to spend no more than `_value` tokens on your behalf
    *
    * @param _spender The address authorized to spend
    * @param _value the max amount they can spend
    */
    function approve(address _spender, uint256 _value) public
    returns (bool success) {
    allowance[msg.sender][_spender] = _value;
    return true;
    }
    /**
    * Set allowance for other address and notify
    *
    * Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it
    *
    * @param _spender The address authorized to spend
    * @param _value the max amount they can spend
    * @param _extraData some extra information to send to the approved contract
    */
    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;
    }
    }
    /**
    * Destroy tokens
    *
    * Remove `_value` tokens from the system irreversibly
    *
    * @param _value the amount of money to burn
    */
    function burn(uint256 _value) public returns (bool success) {
    require(balanceOf[msg.sender] >= _value); // Check if the sender has enough
    balanceOf[msg.sender] -= _value; // Subtract from the sender
    totalSupply -= _value; // Updates totalSupply
    emit Burn(msg.sender, _value);
    return true;
    }
    /**
    * Destroy tokens from other account
    *
    * Remove `_value` tokens from the system irreversibly on behalf of `_from`.
    *
    * @param _from the address of the sender
    * @param _value the amount of money to burn
    */
    function burnFrom(address _from, uint256 _value) public returns (bool success) {
    require(balanceOf[_from] >= _value); // Check if the targeted balance is enough
    require(_value <= allowance[_from][msg.sender]); // Check allowance
    balanceOf[_from] -= _value; // Subtract from the targeted balance
    allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance
    totalSupply -= _value; // Update totalSupply
    emit Burn(_from, _value);
    return true;
    }
    }
  • ?
    전문가 분들때문에 힘이납니다.. 좋은글감사합니다
default debug random = 0 / type = READ / detected = READ

List of Articles
번호 분류 제목 추천 수 조회 수 글쓴이 날짜
961 질문 파이썬 post 구현 질문드립니다. 비박스라는 거래소의 api 를 이용하여 거래하는 프로그램을 만드려고 시도 중입니다.   api 레퍼런스 https://github.com/Biboxcom/api_reference/wiki/api_reference   위 페이지에서 첫 번째 ... 4 0 836
루핑
2018.03.04
960 개발 프로그래밍을 못하시는분들께 무료로 도움을 주고자합니다. 안녕하세요 보로입니다, 많은문의와 외주를 받으며 많은분들이 연락주셧지만 연락을 먼저 못린점에대해 죄송하다는 말씀부터 먼저드립니다 선으로 진행하는 프로젝트가있고, 그건을 진행하면서 ... 8 0 2028
보로씨
2018.03.03
959 개발 삭제한 글입니다 삭제한 글입니다 0 831
글로벌플렛폼
2018.03.02
958 질문 이더리움 공부중인데 방향성을 잃었습니다.     안녕하세요   현재 독학으로 이더리움 스터디 진행중에 도저히 이해가 되지 않는 부분이 생겨 이렇게 질문해 봅니다.  아직 정확하게 개념파악이 되지 않아서 질문 자체가 이상할 수도 있으... 5 0 1735
바다물고기
2018.03.01
957 질문 이더리움 dapp을 개발하고 있는데 궁금한점이 있습니다. 이더리움 dapp을 개발하고 있는데 궁금한점이 있습니다.   고수님들이 많이 계신 여기에 짧게 묻겠습니다. 워낙 하수고 초보라 바보 같은 질문입니다. ㅜㅠ web3를 사용하여 개발을 하고 있는데 ... 3 0 1443
춘천광부
2018.02.28
956 질문 비트렉스api 중에 질문좀 드릴께요. 비트렉스에서 usdt대비 btc 값을 가져오려면 아래 api를 쓰면되는데 https://bittrex.com/api/v1.1/public/getmarketsummary?market=usdt-btc   비트렉스 메인화면에 제공되는 그냥 BTC 가격은 a... 4 0 1293
때가쏙bit
2018.02.28
955 질문 트레이딩봇을만들려고하는데요       후오비기반으로 이용할건데 후오비에서제공하는 API접속KEY로 트리이드봇으로접속해서 매수매도가능한가요?                 ------------------------------------- 꼬리말 * 게시글 내용... 6 0 1606
콰트로폴
2018.02.27
954 개발 가상화폐 자동 트레이딩 개발 프로젝트 내용     &lt;프로젝트 진행 방식&gt;   사전 미팅 후 진행간 매일에 10분 미팅을 진행하고자 합니다.   -1차 개발 비용 2,000 만원 -2차 개발 비용 2,000만원 -3차 개발 비용 2,000만원 -유... 2 0 2079
대전사람
2018.02.27
953 질문 업 ㅂㅌ 분석 2.   각각 다음의 데이터를 뽑았습니다.             &quot;candleDateTime&quot;: &quot;2018-02-26T14:42:00+00:00&quot;,     &quot;candleDateTimeKst&quot;: &quot;2018-02-26T23:42:00+09:00&quot;,     &quot;openingPrice&quot;: 1055.00000000... 1 0 1715
진주
2018.02.26
952 질문 업비트 분석에서     실시간 으로 올라오는 판매가/구매가 / 그 수량들을 각기 뽑아내고자 합니다.   밖에서도 보이는 ajax 결과 값들이 있긴한데   어떤것을 가져와야 .. 현재 시점의 ASK / BID / 각각 가격대의... 1 0 1178
진주
2018.02.26
951 개발 가상화폐 결제 모듈로 사용 가능한 SDK 가 있는지요?   제품 결제를 가상화폐로 할 수 있게 만들어 보고 싶습니다.  연동할 수 있는 솔루션이나 SDK 가 있으면 알려 주세요.   먼저 감사의 말씀 드립니다.      -----------------------------------... 2 0 1426
rocky76
2018.02.26
950 질문 코인 개발을 할때 질문 있습니다.     현재 기존 코인과 차별화 할수 있는 아이디어는 있는데    문제는 제가 기술자가 아니라서 업체를 통해 이를 시장성있는 상품으로 진행하고자 한다면   비용은 어느정도 드는지 궁굼합니다. ... 2 0 984
BT리움
2018.02.26
949 개발 라이트 [완료] 글 내용 수정                         ------------------------------------- 꼬리말 * 게시글 내용 삭제시 레벨 강등 * 질문은 각 주제별 게시판에.   비트코인 암호화화폐 커뮤니티 땡글~ 땡... 1 0 857
아토스
2018.02.25
948 질문 블록체인이 공인인증서를 어떻게 대체할 수 있을까요?     안녕하세요. API 트레이딩 하면서 블록체인을 공부하는 사람입니다. 블록체인이 공인인증서를 대체한다는 신문기사의 내용들이 반갑기는 한데. 제가 공부한 수준으로는 이해가 잘 안 되는 부... 8 0 1278
hbled
2018.02.24
947 질문 코인 차트 개발 추천 좀 부탁드려요 안녕하세요 코인 시세표 차트 만들어야 하는데 혹시 어느 차트는 많이 이용하시나요?   이것 저것 보고 있는데 https://www.chartiq.com/ http://www.modulusglobal.com/products/ https://www.m... 2 0 3932
타스
2018.02.23
946 개발 위변조인증관련 코인을 개발할려고 합니다 팀을짜보고싶은데 강남에서 밋업 하실분 안계신가요 안녕하세요 저를 소개하자면   저는 제네시스,해쉬플레어,oxbtc와 같은 클라우드마이닝으로 앤트마이너S9채굴기상품으로 비트코인을 채굴중인 사람입니다.   270테라정도라 1월장에 비하여 벌이... 4 0 1213
엉ㅇ
2018.02.22
945 개발 스팀 같은 블록체인은 스토리지를 어떻게 운영하나요? 블록체인 기술을 공부하고 있는 기획자입니다.  공부하다가 의문점이 있어 여기 훌륭하신 개발자분들께 질문 좀 드립니다.    스팀(Steem)과 같은 서비스들은 사진을 함께 첨부하기도 하고.. Dtu... 5 0 923
뿌링클
2018.02.22
944 질문 sirin token 혹시 아시는 분 있으면 평가좀..투자했는데 영..거지같아서ㅜㅠ 팔아야하나?           개발자분들 평가하시에 어떤지...  아무래도 한국에서는 많이 알려지지 않은 코인이라 업비트나 비트렉스에 상장 된지도 얼마 안됐습니다.   지금 아마 3.5달러에서 주르륵 내려와서 1... 0 515
sinfree65
2018.02.22
943 개발 업비트 업비트 1 file 0 1735
rlawlgur1
2018.02.22
개발 이더리움과 스마트 컨트랙(2) - 30분만에 ICO 하기 30분만에 ICO하기   안녕하세요. 오늘은 조금 자극적인 제목을 가지고 와봤습니다. 요즘 ICO 많이들 참여하시고,  직접 하시는 분들도 많이 계신데요. ICO에 필요한 토큰을 단 30분 만에 발행하... 28 file 40 8486
파이리
2018.02.22
Board Pagination Prev 1 ... 40 41 42 43 44 45 46 47 48 49 ... 93 Next
/ 93
default debug random = 0 / type = READ / detected = READ