Ethereum은 사용성이 중요하다.

안녕하세요, Staked 와타나베 창태입니다. 이번에는 사용성에 대해 씁니다.

사용성의 과제



블록체인에서는 스케일링은 프라이버시의 문제가 많이 논의되지만, UI와 UX를 포함한 사용성도 매우 큰 문제입니다. 예를 들어, Ethereum상에서 발행된 토큰인 ERC20( DAI라든지 ZRX라든지)을 보낼 때 gas라고 불리는 수수료가 필요합니다. 이것은 Ethereum의 고유 통화인 Ether로 지불됩니다.

예를 들어 ZRX를 보내고 싶습니다. Metamask의 이 화면에서 볼 수 있듯이 거래 수수료는 Ether로 표시됩니다.


이것이라고 ERC20 토큰이나 ERC721 디지털 자산을 가지고 있지만, Ether를 가지고 있지 않은 사람은 잔고 부족이 되어 거래를 할 수 없습니다. Vitalik이 Ethereum Research 에서도 언급했듯이 ERC20에서 gas를 지불하는 것은 복잡한 작업이 필요하고 어려워지고 있습니다.



또 다른 분산형 거래소의 프로토콜을 만들고 있는 0x를 예로 들겠습니다. 다음은 주문 형식입니다. 과거 0x에 대한 기사는 나의 다른 출력에서 ​​참조하십시오. .



현재 많은 릴레이가 수수료를 갖고 있지 않기 때문에, ZRX를 가지고 있지 않아도 트레이딩은 할 수 있습니다만, 수수료를 취하는 경우, ZRX를 가지고 있지 않으면 수수료를 취할 수 없는 모델은 인센티브 설계로서 능숙하지 않습니다. ZRX는 거버넌스 토큰으로서의 역할이 있으며, ZRX를 사용하고 있는 사람, 가지고 있는 사람이 0x의 거버넌스를 하도록(듯이) 설계하고 있습니다. 기분은 알겠지만 유저빌리티로서는 좋지 않다고 생각합니다.

제안된 솔루션



이 문제에 대해 EIP(Ethereum Improvement Proposal) 856번 에서 제안이 있었으므로 간단하게 소개하고 싶습니다. 커뮤니티 내에서 논의되고 있어 개선도 되고 있습니다만 여기에서는 오리지날의 아이디어를 사용하고 싶습니다.

사양


  • A: 보낸 사람
  • B: 수신자
  • D: 위임자
  • X : A에서 B로 전송되는 토큰의 양
  • Y : A에서 D로 보내지는 수수료
  • T: 토큰
  • N: 넌스
  • ERC20 토큰을 보내고 싶지만 ETH를 가지고 있지 않은 사용자 A는 사용자 B에게 송금하기 위해 위탁자 D(대리자)가 설정한 비율에 따라 전송하고 싶은 ERC20 토큰과 ETH gas 요금과 같은 양의 ERC20 을 올려 위탁자 D에게 송금합니다.
  • 사용자 A는 자신의 프라이빗 키를 바탕으로 타원 암호 곡선으로 생성한 값(V,R,S)과 P(넌스, Sneder의 주소, Recipient의 주소, Delegate의 주소, A가 D에 곱한다. 토큰, A에서 B로 보내지는 토큰, 보낼 토큰)을 D로 보냅니다.
  • D 는 이것을 이용해 트랜잭션(transaction)가 도중에 개조되고 있지 않은지를 검증합니다.
  • D는 자신의 계정에서 Ethereum 네트워크로 트랜잭션을 제출합니다. 구체적으로 D는 makerFee 명령을 두드린다.
  • Ethereum에서 트랜잭션이 자동 집행됨으로써 A에서 B, A에서 D로 자동 송금됩니다.

  • 방법



    위탁자가 온체인 트랜잭션을 수행할 때 call되는 함수

    transferPreSigned
    function transferPreSigned(
        bytes _signature,
        address _to,
        uint256 _value,
        uint256 _fee,
        uint256 _nonce
    )
        public
        returns (bool);
    

    TransactionReceipt의 logs에 Event를 긁을 때 사용할 event
    event TransferPreSigned(address indexed from, address indexed to, address indexed delegate, uint256 amount, uint256 fee);
    

    온 체인에서 처리
        function transferPreSigned(
            //オーナーによって生成される署名のバイトキー
            bytes _signature,
            //送信したい相手先のアドレス
            address _to,
            //送金したい値
            uint256 _value,
         //トークンオーナーによって委託者に支払われる値段
            uint256 _fee,
         //ナンス
            uint256 _nonce
        )
            public
            returns (bool)
        {
         //GOXを防ぐ
            require(_to != address(0));
            require(signatures[_signature] == false);
        
            //送信をハッシュ化
            bytes32 hashedTx = transferPreSignedHashing(address(this), _to, _value, _fee, _nonce);
            //ハッシュの復号化から検証
            address from = recover(hashedTx, _signature);
            require(from != address(0));
    
         //送った後の処理
            balances[from] = balances[from].sub(_value).sub(_fee);
            balances[_to] = balances[_to].add(_value);
            balances[msg.sender] = balances[msg.sender].add(_fee);
            signatures[_signature] = true;
    
            Transfer(from, _to, _value);
            Transfer(from, msg.sender, _fee);
            TransferPreSigned(from, _to, msg.sender, _value, _fee);
            return true;
        }
    
        function transferPreSignedHashing(
            address _token,
            address _to,
            uint256 _value,
            uint256 _fee,
            uint256 _nonce
        )
            public
            pure
            returns (bytes32)
        {
            /* "48664c16": transferPreSignedHashing(address,address,address,uint256,uint256,uint256) */
            return keccak256(bytes4(0x48664c16), _token, _to, _value, _fee, _nonce);
        }
    

    좋은 웹페이지 즐겨찾기