Plasma Cash 계약 해독

원본 링크:http://www.cnblogs.com/baizx/p/9649153.html
Plasma Cash 계약 해독
  • SmartPlasma 계약 해석
  • 1. 계약 코드
  • 2. 계약 문서 에 대한 간단 한 소개
  • 3. Plasma Cash 의 기초 데이터 구조
  • 3.1 Plasma Cash 중의 자산
  • 3.2 Plasma Cash 에서 의 거래
  • 3.3 Plasma Cash 중의 Block
  • 3.4 Plasma Cash 에서 자산 의 회귀 메 인체 인 이 더 리 움
  • 3.4.1 자산 보유 증명
  • 3.4.2 다른 사람 이 나 에 게 도전 하 기 를 기다린다
  • 3.4.3 도전 기간 이 지 났 고 Bob 은 자산 uid
  • 를 되 찾 았 다.

  • 4. Plasma Cash 의 탈퇴 예시
  • 5. 기타 질문 Plasma 는 V 신 이 2017 년 8 월 에 제기 한 것 으로 체인 거래 를 통 해 이 더 리 움 의 TPS 를 대폭 향상 시 키 고자 한다.

  • 모든 Plasma 체인 은 거래 순서 에 관 한 정 보 를 하나의 해시 값 으로 환산 하여 루트 체인 에 저장 합 니 다.비트 코 인과 이 더 리 움 은 모두 루트 체인 에 속한다. 이 두 블록 체인 은 매우 높 은 안전성 을 가지 고 탈 중심 화 를 통 해 (안전성 과 활성) 을 확보 했다.
    Plasma 디자인 모델 은 두 가지 주요 한 부분 이 있 는데 그것 이 바로 Plasma MVP 와 Plasma Cash 이다.여기 서 우 리 는 스마트 플 라 즈 마 가 실현 한 플 라 즈 마 캐 시 계약 을 연구 하고 계약 분석 을 통 해 플 라 즈 마 캐 시 에 관 한 일련의 의문 에 대답 합 니 다.
    1. 계약 코드
    SmartPlasma 의 계약 코드 는 계속 업 그 레이 드 될 것 입 니 다. 저 는 그들 이 오늘 (2018 - 09 - 14) 최신 버 전에 대해 분석 을 했 습 니 다. 이 코드 는 현재 제 github 에 저 장 된 plasma cash 입 니 다.
    2. 계약서 에 대한 간단 한 소개
    폴 더 에는 Plasma Cash 와 무관 한 계약 이 적지 않 습 니 다. 여 기 는 Plasma Cash 와 직접 관련 된 계약 에 만 관심 을 가지 고 있 습 니 다. 예 를 들 어 ERC 20 Token 과 관련 된 계약 은 무시 하고 스스로 확인 합 니 다.
  • Mediator. sol 은 Plasma Cash 체인 에서 자산 의 수출입
  • 이다.
  • RootChain. sol 처리 Plasma Cash 서브 체인 (이 더 리 움 에 비해) 중의 거래 및 포장 등
  • libraries / MerkleProof. sol 은 서브 체인 에서 거래 하 는 데 사용 되 는 메 르 켈 트 리 로 서브 체인 참여 자 에 게 사기 증명 fraud proof.
  • libraris / RLP. sol RLP 인 코딩 지원 은 잠시 무시 할 수 있 습 니 다. 서브 체인 의 모든 거래 는 RLP 로 인 코딩 됩 니 다.
  • libraries / PlasmaLib. sol 생 성 uid 의 보조 함수
  • ECRecovery. sol 서명 검증
  • datastructures / Transaction. sol 거래 의 데이터 구조 설명
  • 3. Plasma Cash 의 기본 데이터 구조
    Plasma Cash 는 피 드 체인 구조 로 Plasma Cash 는 이 더 리 움 의 하 나 는 = 간단 한 UTXO 모델 을 바탕 으로 하 는 서브 체인 이 라 고 볼 수 있다.
    3.1 Plasma Cash 의 자산
    Plasma Cash 의 자산 은 모두 이 더 리 움 에서 나 왔 지만 Plasma Cash 에 들 어가 면 유일한 ID 를 가지 고 분할 할 수 없습니다. Mediator. sol 의 deposit 함 수 를 참고 할 수 있 습 니 다. Mediator 는 Plasma Cash 자산 을 보관 하 는 곳 입 니 다.
            /** @dev Adds deposits on Smart Plasma.
         *  @param currency Currency address.
         *  @param amount Amount amount of currency.
         */
        function deposit(address currency, uint amount) public {
            require(amount > 0);
    
            Token token = Token(currency);
            token.transferFrom(msg.sender, this, amount); /// deposit test1
    
            bytes32 uid = rootChain.deposit(msg.sender, currency, amount); /// deposit test2
            cash[uid] = entry({
                currency: currency,
                amount: amount
            });
        }
    

    계약 을 통 해 알 수 있 듯 이 Plasma Cash 에 들 어간 자산 은 반드시 ERC 20 Token 이 어야 한다. 이런 자산 은 실제 적 으로 Mediator 라 는 계약 에 존재 한 다음 에 Root Chain 이 그 에 게 유일한 ID, 즉 uid 를 분배 해 야 한다. 이 uid 는 어떤 token 을 대표 하 는 지, 몇 개가 있 는 지 를 나타 낸다.
    3.2 Plasma Cash 에서 의 거래
    키 코드 는 Transaction. sol 에 있 습 니 다.
        struct Tx {
            uint prevBlock;
            uint uid;
            uint amount;
            address newOwner;
            uint nonce;
            address signer;
            bytes32 hash;
        }
    

    여 기 는 분명 하지 않 을 수 있 습 니 다. 설명 이 필요 해 야 UTXO 거래 모델 임 을 알 수 있 습 니 다. 이 안의 amount 와 hash 는 실제 적 으로 다소 수 다스 러 워 서 무시 할 수 있 습 니 다. 그러면 나머지 멤버 들 은 설명 이 필요 합 니 다.prevBlock 바로 UTXO 의 입력 입 니 다. 어느 부분 에서 왔 습 니까? 비트 코 인 과 같은 OutPoint 구조 가 없 는 이 유 는 TxHash + Index 입 니 다. 나중에 말씀 드 리 겠 습 니 다. uid 거래 된 자산 ID newOwner 거래 가 누구 에 게 수출 되 는 지 에 대해 서도 비트 코 인 과 같은 스 크 립 트 를 지원 하지 않 습 니 다. nonce 이 자산 의 몇 번 째 거래 입 니까?쌍 화 증명 에 중요 한 역할 을 한다. signer 자산 원 소유자 의 서명 이 있어 야 한다.amount 중요 하지 않 은 것 은 자산 을 분할 할 수 없 기 때문에 이곳 의 Amount 는 거래 에 따라 변화 가 발생 하지 않 고 hash 는 직접 계산 할 수 있다.
    3.3 Plasma Cash 의 Block
    만약 에 일반 블록 체인 중의 Block 과 같다 면 그 는 거래 의 집합 이다. 그러나 일반 체인 과 달리 이 안의 광부 (Operator 가 아니 라) 는 서브 체인 을 잘 유지 해 야 할 뿐만 아니 라 모든 Block 에 대응 하 는 메 르 켈 나무 뿌리 를 이 더 리 움 에 주기 적 으로 저장 해 야 한다. 이 작업 은 Operator 만 완성 할 수 있다. 구체 적 인 코드 는 RootChain. sol 을 볼 수 있다.
        function newBlock(bytes32 hash) public onlyOperator {
            blockNumber = blockNumber.add(uint256(1));
            childChain[blockNumber] = hash;
    
            NewBlock(hash);
        }
    

    거래 증거 제출 자 는 Operator, 즉 계약 의 창시자 일 수 있 습 니 다. 이 Operator 는 일반 계좌 일 수도 있 습 니 다. 이때 그 가 바로 이 서브 체인 의 관리자 일 수도 있 고 계약 일 수도 있 습 니 다. 그러면 계약 을 통 해 서브 체인 의 블록 규칙 을 규정 할 수 있 습 니 다.
    3.4 Plasma Cash 에서 자산 의 회귀 메 인체 인 이 더 리 움
    자산 이 Plasma 에서 한동안 거래 된 후에 소지 자 Bob 이 Plasma Cash 서브 체인 에서 탈퇴 하려 면 이 더 리 움 계약, 즉 Root Chain 에 이 자산 을 가지 고 있다 는 것 을 증명 해 야 한다.
    3.4.1 자산 보유 증명서
    이 사고방식 은 UTXO 의 사고방식 과 같다. Bob 은 이 자산 이 어디에서 나 에 게 넘 어 왔 는 지 증명 할 수 있다. 구체 적 으로 RootChain. sol 중의 startExit 함 수 를 볼 수 있다. 그 사고방식 은 매우 간단 하고 증명 할 수 있다.
  • 이 자산 은 어디에서 왔 습 니까? (어느 M 블록 에서 Alice 에 게 이전 되 었 습 니까?)
  • Alice 사인 을 거 쳐 Bob (N 조각 에서 Alice 가 사인 을 해 주 었 다) 에 게 옮 겼 습 니 다. 코드 를 구체 적 으로 보 세 요 startExit
  • /** @dev Starts the procedure for withdrawal of the deposit from the system.
         *  @param previousTx Penultimate deposit transaction.
         *  @param previousTxProof Proof of inclusion of a penultimate transaction in a Smart Plasma block.
         *  @param previousTxBlockNum The number of the block in which the penultimate transaction is included.
         *  @param lastTx Last deposit transaction.
         *  @param lastTxProof Proof of inclusion of a last transaction in a Smart Plasma block.
         *  @param lastTxBlockNum The number of the block in which the last transaction is included.
         */
        function startExit(
            bytes previousTx,
            bytes previousTxProof,
            uint256 previousTxBlockNum,
            bytes lastTx,
            bytes lastTxProof,
            uint256 lastTxBlockNum
        )
            public
        {
            Transaction.Tx memory prevDecodedTx = previousTx.createTx();
            Transaction.Tx memory decodedTx = lastTx.createTx();
            //     prevBlock    Alice      uid
            require(previousTxBlockNum == decodedTx.prevBlock);
            require(prevDecodedTx.uid == decodedTx.uid);
            //amount   ,        
            require(prevDecodedTx.amount == decodedTx.amount);
            //Alice          ,            
            require(prevDecodedTx.newOwner == decodedTx.signer);
            require(decodedTx.nonce == prevDecodedTx.nonce.add(uint256(1))); //        
            //   Bob,          
            require(msg.sender == decodedTx.newOwner);
            require(wallet[bytes32(decodedTx.uid)] != 0);
    
            bytes32 prevTxHash = prevDecodedTx.hash;
            bytes32 prevBlockRoot = childChain[previousTxBlockNum];
            bytes32 txHash = decodedTx.hash;
            bytes32 blockRoot = childChain[lastTxBlockNum];
    
            require(
                prevTxHash.verifyProof(
                    prevDecodedTx.uid,
                    prevBlockRoot,
                    previousTxProof
                )
            );
            require(
                txHash.verifyProof(
                    decodedTx.uid,
                    blockRoot,
                    lastTxProof
                )
            );
    
            /// Record the exit tx.
            require(exits[decodedTx.uid].state == 0);
            require(challengesLength(decodedTx.uid) == 0);
    
            exits[decodedTx.uid] = exit({
                state: 2,
                exitTime: now.add(challengePeriod),
                exitTxBlkNum: lastTxBlockNum,
                exitTx: lastTx,
                txBeforeExitTxBlkNum: previousTxBlockNum,
                txBeforeExitTx: previousTx
            });
    
            StartExit(prevDecodedTx.uid, previousTxBlockNum, lastTxBlockNum);
        }
    

    코드 의 절반 은 lastTxBlockNum 에 있 을 때 자산 uid 가 Bob 에 게 있다 는 것 을 증명 하 는 데 사 용 됩 니 다. 그리고 절반 은 Bob 이 자산 uid 를 가 져 가 려 고 합 니 다. 제 생각 은 계약 에 잠시 보관 하고 다른 사람 이 도전 하 기 를 기다 리 겠 습 니 다.
    3.4.2 다른 사람 이 나 에 게 도전 하 기 를 기다린다.
    이상 의 정보 가 있 으 면 N 블록 에 있 을 때 이 자산 은 Bob 이 사용 한 것 임 을 증명 할 수 있 습 니 다. 그러나 이것 은 분명 부족 합 니 다. 현재 자산 이 Bob 에 속 한 다 는 것 을 증명 할 수 없고 Alice 가 M 블록 이후 에 다른 사람 에 게 주지 않 았 다 는 것 을 증명 할 수 없습니다. M 블록 에 있 을 때 Alice 가 정말 uid 의 소유자 라 는 것 을 증명 할 수 없습니다.이런 문제 들 은 대답 하기 어 려 울 것 같 지만 사실은 생각 도 간단 하 다. 이 생각 은 뇌 전 네트워크 에서 문 제 를 해결 하 는 방법 과 똑 같 아서 이 자산 의 이해관계 자 를 나서서 증 거 를 제시 하 게 한다. 예 를 들 어 캐 롤 이 이 자산 Bob 을 입증 할 수 있다 면 사실은 Bob 은 쌍 화 이다. 구체 적 인 도전 과 영전 코드 가 비교적 복잡 하 다.그러나 이것 도 Plasma Cash 의 핵심 안전성 이다. 이런 것들 이 없 으 면 모든 참여 자 들 이 자신의 권익 을 보장 할 수 없다.
    //challengeExit     uid       Bob
      /** @dev Challenges a exit.
         *  @param uid Unique identifier of a deposit.
         *  @param challengeTx Transaction that disputes an exit.
         *  @param proof Proof of inclusion of the transaction in a Smart Plasma block.
         *  @param challengeBlockNum The number of the block in which the transaction is included.
         */
        function challengeExit(
            uint256 uid,
            bytes challengeTx,
            bytes proof,
            uint256 challengeBlockNum
        )
            public
        {
            require(exits[uid].state == 2);
    
            Transaction.Tx memory exitDecodedTx = (exits[uid].exitTx).createTx();
            Transaction.Tx memory beforeExitDecodedTx = (exits[uid].txBeforeExitTx).createTx();
            Transaction.Tx memory challengeDecodedTx = challengeTx.createTx();
    
            require(exitDecodedTx.uid == challengeDecodedTx.uid);
            require(exitDecodedTx.amount == challengeDecodedTx.amount);
    
            bytes32 txHash = challengeDecodedTx.hash;
            bytes32 blockRoot = childChain[challengeBlockNum];
    
            require(txHash.verifyProof(uid, blockRoot, proof));
    
            // test challenge #1 & test challenge #2                 , Bob      
            if (exitDecodedTx.newOwner == challengeDecodedTx.signer &&
            exitDecodedTx.nonce < challengeDecodedTx.nonce) {
                delete exits[uid];
                return;
            }
    
            // test challenge #3,    ,  Alice      ,      Carol BlockNumer   ,        .
            if (challengeBlockNum < exits[uid].exitTxBlkNum &&
                (beforeExitDecodedTx.newOwner == challengeDecodedTx.signer &&
                challengeDecodedTx.nonce > beforeExitDecodedTx.nonce)) {
                delete exits[uid];
                return;
            }
    
            // test challenge #4     M   ,      ,Alice         M       uid
            if (challengeBlockNum < exits[uid].txBeforeExitTxBlkNum ) {
                exits[uid].state = 1;
                addChallenge(uid, challengeTx, challengeBlockNum);
            }
    
            require(exits[uid].state == 1);
    
            ChallengeExit(uid);
        }
    
    //Bob  ,    ,                 ,         ,     Alice   M      uid
     /** @dev Answers a challenge exit.
         *  @param uid Unique identifier of a deposit.
         *  @param challengeTx Transaction that disputes an exit.
         *  @param respondTx Transaction that answers to a dispute transaction.
         *  @param proof Proof of inclusion of the respond transaction in a Smart Plasma block.
         *  @param blockNum The number of the block in which the respond transaction is included.
         */
        function respondChallengeExit(
            uint256 uid,
            bytes challengeTx,
            bytes respondTx,
            bytes proof,
            uint blockNum
        )
            public
        {
            require(challengeExists(uid, challengeTx));
            require(exits[uid].state == 1);
    
            Transaction.Tx memory challengeDecodedTx = challengeTx.createTx();
            Transaction.Tx memory respondDecodedTx = respondTx.createTx();
    
            require(challengeDecodedTx.uid == respondDecodedTx.uid);
            require(challengeDecodedTx.amount == respondDecodedTx.amount);
            require(challengeDecodedTx.newOwner == respondDecodedTx.signer);
            require(challengeDecodedTx.nonce.add(uint256(1)) == respondDecodedTx.nonce);
            require(blockNum < exits[uid].txBeforeExitTxBlkNum);
    
            bytes32 txHash = respondDecodedTx.hash;
            bytes32 blockRoot = childChain[blockNum];
    
            require(txHash.verifyProof(uid, blockRoot, proof));
    
            removeChallenge(uid, challengeTx);
    
            if (challengesLength(uid) == 0) {
                exits[uid].state = 2;
            }
    
            RespondChallengeExit(uid);
        }
    

    3.4.3 도전 기간 이 지나 면 Bob 은 자산 uid 를 되 찾 습 니 다.
    도전 기간 이 지난 후 Bob 은 Mediator. sol 에서 자산 을 이 태 방 으로 돌려 보 내 자고 제안 했다.
     /** @dev withdraws deposit from Smart Plasma.
         *  @param prevTx Penultimate deposit transaction.
         *  @param prevTxProof Proof of inclusion of a penultimate transaction in a Smart Plasma block.
         *  @param prevTxBlkNum The number of the block in which the penultimate transaction is included.
         *  @param txRaw lastTx Last deposit transaction.
         *  @param txProof Proof of inclusion of a last transaction in a Smart Plasma block.
         *  @param txBlkNum The number of the block in which the last transaction is included.
         */
        function withdraw(
            bytes prevTx,
            bytes prevTxProof,
            uint prevTxBlkNum,
            bytes txRaw,
            bytes txProof,
            uint txBlkNum
        )
            public
        {
            bytes32 uid = rootChain.finishExit(
                msg.sender,
                prevTx,
                prevTxProof,
                prevTxBlkNum,
                txRaw,
                txProof,
                txBlkNum
            );
    
            entry invoice = cash[uid];
    
            Token token = Token(invoice.currency);
            token.transfer(msg.sender, invoice.amount); ///        
    
            delete(cash[uid]); 
        }
    

    RootChain 재 검증
     /** @dev Finishes the procedure for withdrawal of the deposit from the system.
         *       Can only call the owner. Usually the owner is the mediator contract.
         *  @param account Account that initialized the deposit withdrawal.
         *  @param previousTx Penultimate deposit transaction.
         *  @param previousTxProof Proof of inclusion of a penultimate transaction in a Smart Plasma block.
         *  @param previousTxBlockNum The number of the block in which the penultimate transaction is included.
         *  @param lastTx Last deposit transaction.
         *  @param lastTxProof Proof of inclusion of a last transaction in a Smart Plasma block.
         *  @param lastTxBlockNum The number of the block in which the last transaction is included.
         */
        function finishExit(
            address account,
            bytes previousTx,
            bytes previousTxProof,
            uint256 previousTxBlockNum,
            bytes lastTx,
            bytes lastTxProof,
            uint256 lastTxBlockNum
        )
            public
            onlyOwner
            returns (bytes32)
        {
            Transaction.Tx memory prevDecodedTx = previousTx.createTx();
            Transaction.Tx memory decodedTx = lastTx.createTx();
    
            require(previousTxBlockNum == decodedTx.prevBlock);
            require(prevDecodedTx.uid == decodedTx.uid);
            require(prevDecodedTx.amount == decodedTx.amount);
            require(prevDecodedTx.newOwner == decodedTx.signer);
            require(account == decodedTx.newOwner);
    
            bytes32 prevTxHash = prevDecodedTx.hash;
            bytes32 prevBlockRoot = childChain[previousTxBlockNum];
            bytes32 txHash = decodedTx.hash;
            bytes32 blockRoot = childChain[lastTxBlockNum];
    
            require(
                prevTxHash.verifyProof(
                    prevDecodedTx.uid,
                    prevBlockRoot,
                    previousTxProof
                )
            );
    
            require(
                txHash.verifyProof(
                    decodedTx.uid,
                    blockRoot,
                    lastTxProof
                )
            );
    
            require(exits[decodedTx.uid].exitTime < now); //     
            require(exits[decodedTx.uid].state == 2); //                   
            require(challengesLength(decodedTx.uid) == 0);
    
            exits[decodedTx.uid].state = 3;
    
            delete(wallet[bytes32(decodedTx.uid)]);
    
            FinishExit(decodedTx.uid);
    
            return bytes32(decodedTx.uid);
        }
    

    4. Plasma Cash 의 종료 예시
    sequenceDiagram participant o as operator participant u1 as alice participant u2 as bob participant u3 as carol participant u4 as david u1 - > > rootchain: deposit asset to RootChain, get unique id asset 1 o - > rootchain: 생 성 NewBlock 3, 기록 이 자산 u1 - > > u2: transfer asset 1 to bob o - > > rootchain: 생 성 NewBlock 7,이 거래 u1 - > u3: transfer asset 1 to carol o - > rootchain: Newblock 11 을 생 성하 여 이 거래 u3 - > rootchain 을 기록 합 니 다. 저 는 asset 1 을 메 인 체인 으로 인출 하고 asset 1 을 alice 에서 제공 하 며 alice 에서 서명 하여 11 u2 - > rootchain 에서 발생 합 니 다. 도전 을 제기 합 니 다. asset 1 은 저 에 게 속 해 야 합 니 다. asset 1 을 제공 하고 alice 에서 서명 하 며 7 에서 발생 합 니 다. rootchain 은 bob 증거 가 유효 하 다 고 판단 합 니 다.carol 현금 인출 거부 u2 - > u4: transfer asset 1 to devid o - > rootchain: Newblock 27 생 성, 이 거래 기록 u4 - > rootchain: 현금 인출 asset 1, bob 에서 왔 습 니 다. bob 의 서명 이 있 습 니 다. 27 loop David wait for challenge u4 - > u4: 도전 기 2 주 동안 end u4 - > rootchain: withdraw, 현금 인출, asset 1 을 rootchain 에서 전환 합 니 다.
    5. 기타 문제
  • 왜 Plasma Cash 중의 자산 은 분할 할 수 없 습 니까?rootchain 에 들 어간 자산 은 비트 코 인의 UTXO 모델 과 유사 하지만 분할 할 수 없습니다. 이것 은 거래 검증 을 통 해 매번 amount 가 변 하지 않도록 요구 할 수 있 습 니 다.
  • operator 의 역할 은 무엇 입 니까?operator 는 서브 체인 의 거래 증거 (메 르 켈 트 리) 를 이 더 리 움 메 인 체인 에 제출 하 는 것 을 책임 집 니 다.
  • operator 는 믿 을 수 있어 야 합 니까?예. operator 는 타인 의 자산 을 마음대로 이전 할 수 없 지만 타인 의 자산 이전 을 막 을 수 있 습 니 다. 즉, Plasma 서브 체인 에서 이 더 리 움 으로 돌아 갈 수 없습니다. 물론 이 부분 은 개선 되 고 operator 의 악행 으로 인 한 위험 을 낮 출 수 있 습 니 다.
  • operator 는 계약 이 될 수 있 습 니까?예. operator 가 Pos 공감 대 계약 이 라면 문제 3 의 위험 을 낮 출 수 있 습 니 다

  • 다음으로 전송:https://www.cnblogs.com/baizx/p/9649153.html

    좋은 웹페이지 즐겨찾기