6.區(qū)塊鏈節(jié)點(diǎn)信息同步

區(qū)塊鏈節(jié)點(diǎn)信息需要同步,本節(jié)主要講一下選取最長的鏈做為基準(zhǔn)鏈。

NiuCoinBlockChainOne.py

# -*- coding: utf-8 -*-
from typing import Any,Dict,List,Optional
import time
import hashlib
from uuid import uuid4
import json
from flask import Flask
from flask import jsonify
from urllib.parse import urlparse
from flask import request
import requests

class NiuCoinBlockChainOne:

    # 構(gòu)造器
    def __init__(self):
        self.current_transcations=[]#緩存交易列表,在沒有新區(qū)塊前放在這里,產(chǎn)生新區(qū)塊后,會(huì)被加入到新區(qū)塊
        self.chain=[]#區(qū)塊鏈管理多個(gè)區(qū)塊
        self.nodes=set()#保存網(wǎng)絡(luò)中的其它節(jié)點(diǎn)
        self.new_block(pre_hash="1",proof=100)#創(chuàng)世區(qū)塊

    #新增一個(gè)新區(qū)塊
    def new_block(self,pre_hash:Optional[str],proof:int)->Dict[str,Any]:
        block = {
            "index":len(self.chain)+1, #索引
            "timestamp":time.time(),
            "transcations":self.current_transcations,#將臨時(shí)緩存的交易放在區(qū)塊中
            "proof":proof,#工作量要記下來,校驗(yàn)區(qū)塊時(shí)需要這個(gè)證明
            "pre_hash":pre_hash or self.chain[-1]["hash"]
        }
        block["hash"] = self.hash(block)
        self.current_transcations=[]#交易被打包成區(qū)塊后,要清空
        self.chain.append(block)

    #新增一個(gè)新的交易
    def new_transcations(self,sender:str,recer:str,amount:int)->int:
        self.current_transcations.append({
            "sender":sender,
            "recer":recer,
            "amount":amount,
        })
        return self.last_block()["index"]+1

    # 獲得最后一個(gè)區(qū)塊
    def last_block(self)->Dict[str,Any]:
        return self.chain[-1]

    # 整個(gè)區(qū)塊hash
    @staticmethod
    def hash(block:Dict[str,Any])->str:
        blockstring = json.dumps(block,sort_keys=True).encode()
        return hashlib.sha256(blockstring).hexdigest()

    # 不斷修改值,進(jìn)行hash碰撞,起到算出結(jié)果為止(即拿到證明)
    def proof_of_work(self,last_proof:int)->int:
        proof = 0
        while self.do_proof(last_proof,proof) is False:
            proof+=1
        return proof

    # 進(jìn)行hash碰撞
    @staticmethod
    def do_proof(last_proof:int,proof:int)->bool:
        guess = f'{last_proof*proof}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4]=="0000"#難度可調(diào)

    # 校驗(yàn)整個(gè)鏈?zhǔn)欠裾_
    def valid_chain(self,chain:List[Dict[str,Any]]):
        #用當(dāng)前區(qū)塊與前一個(gè)區(qū)塊進(jìn)行校驗(yàn),循環(huán)至最后一個(gè)
        pre_block = chain[0]
        current_index = 1
        while current_index<len(chain):
            block = chain[current_index]
            if block["pre_hash"]!=self.hash(pre_block): #校驗(yàn)是否被篡改,hash要能對上
                return False
            if not self.valid_proof(pre_block["proof"],block["proof"]):#校驗(yàn)工作量正確
                return False
            pre_block = block
            current_index+=1
        return True

    # 節(jié)點(diǎn)注冊,追加節(jié)點(diǎn)
    def register_node(self,addr:str)->None:
        now_url=urlparse(addr)#將addr轉(zhuǎn)成對象,能取出schame或port等
        self.nodes.add(now_url.netloc)#netloc='www.cwi.nl:80'

    #節(jié)點(diǎn)同步:查找所有的節(jié)點(diǎn),如果附近的節(jié)點(diǎn)比自己多,將鄰居節(jié)點(diǎn)的鏈賦值給自己節(jié)點(diǎn)
    def resolve_conflicts(self)->bool:
        neighbours=self.nodes
        new_chain=None
        max_length=len(self.chain)
        for node in neighbours:#從鄰居中取最長的鏈,賦值給new_chain
            response = requests.get(f"http://{node}/chain") #node的域名與端口都不一樣
            if response.status_code==200:
                length = response.json()["length"]
                chain = response.json()["chain"]
                if length > max_length and self.valid_chain(chain):
                    max_length = length
                    new_chain = chain
        if new_chain:
            self.chain = new_chain#將最長的鏈賦值給自己
            return True
        return False

niucoin = NiuCoinBlockChainOne()
node_id = str(uuid4()).replace("-","")
print("當(dāng)前節(jié)點(diǎn)錢包地址:",node_id)

app = Flask(__name__)
@app.route("/")
def index_page():
    return "歡迎呵呵"

@app.route("/chain")
def chain():#輸出區(qū)塊鏈
    response={
        "chain":niucoin.chain,
        "length":len(niucoin.chain),
    }
    return jsonify(response),200

@app.route("/mine")#挖礦,系統(tǒng)獎(jiǎng)勵(lì)比特幣
def index_mine():
    last_block = niucoin.last_block()
    last_proof = last_block["proof"]
    proof = niucoin.proof_of_work(last_proof) #挖礦,挖到礦才往下走

    niucoin.new_transcations("0",node_id,200) #獲得獎(jiǎng)勵(lì)

    niucoin.new_block(None,proof)
    response={
        "message":"新的區(qū)塊產(chǎn)生",
        "index":niucoin.last_block()["index"],
        "transcations":niucoin.last_block()["transcations"],
        "proof":niucoin.last_block()["proof"],
        "pre_hash":niucoin.last_block()["pre_hash"]
    }

    return jsonify(response),200

@app.route("/new_transcations",methods=["POST"])#交易
def new_transcations():
    values = request.get_json()
    required = ["payer","recer","amount"]
    if not all(key in values for key in required):
        return "數(shù)據(jù)不完整",400
    index = niucoin.new_transcations(values["payer"],values["recer"],values["amount"])
    response = {
        "message":f"交易加入到區(qū)塊{index}"
    }
    return jsonify(response),200

@app.route("/new_node",methods=["POST"])#新增一個(gè)節(jié)點(diǎn)
def new_node():
    values = request.get_json()
    nodes = values.get("nodes")#獲得所有節(jié)點(diǎn)
    if nodes is None:
        return "數(shù)據(jù)有問題",400
    for node in nodes:
        niucoin.register_node(node) #加入節(jié)點(diǎn)
    response = {
        "message":f"節(jié)點(diǎn)已經(jīng)追加",
        "node":list(niucoin.nodes)
    }
    return jsonify(response),200

@app.route("/node_synchronize")#節(jié)點(diǎn)信息同步
def node_refresh():
    replaced = niucoin.resolve_conflicts() #最長的鏈
    if replaced:
        response={
            "message":"區(qū)塊鏈查新為最長區(qū)塊鏈",
            "new_chain":niucoin.chain
        }
    else:
        response = {
            "message": "區(qū)塊鏈已經(jīng)是最長的,無需替換",
            "new_chain": niucoin.chain
        }
    return jsonify(response), 200

if __name__ == "__main__":
    app.run("127.0.0.1",port=65531)

NiuCoinBlockChainTwo.py

# -*- coding: utf-8 -*-
from typing import Any,Dict,List,Optional
import time
import hashlib
from uuid import uuid4
import json
from flask import Flask
from flask import jsonify
from urllib.parse import urlparse
from flask import request
import requests

class NiuCoinBlockChainTwo:

    #構(gòu)造器
    def __init__(self):
        self.current_transcations=[]#緩存交易列表,在沒有新區(qū)塊前放在這里,產(chǎn)生新區(qū)塊后,會(huì)被加入到新區(qū)塊
        self.chain=[]#區(qū)塊鏈管理多個(gè)區(qū)塊
        self.nodes=set()#保存網(wǎng)絡(luò)中的其它節(jié)點(diǎn)
        self.new_block(pre_hash="1",proof=100)#創(chuàng)世區(qū)塊

    #新增一個(gè)新區(qū)塊
    def new_block(self,pre_hash:Optional[str],proof:int)->Dict[str,Any]:
        block = {
            "index":len(self.chain)+1, #索引
            "timestamp":time.time(),
            "transcations":self.current_transcations,#將臨時(shí)緩存的交易放在區(qū)塊中
            "proof":proof,#工作量要記下來,校驗(yàn)區(qū)塊時(shí)需要這個(gè)證明
            "pre_hash":pre_hash or self.chain[-1]["hash"]
        }
        block["hash"] = self.hash(block)
        self.current_transcations=[]#交易被打包成區(qū)塊后,要清空
        self.chain.append(block)

    #新增一個(gè)新的交易
    def new_transcations(self,sender:str,recer:str,amount:int)->int:
        self.current_transcations.append({
            "sender":sender,
            "recer":recer,
            "amount":amount,
        })
        return self.last_block()["index"]+1

    # 獲得最后一個(gè)區(qū)塊
    def last_block(self)->Dict[str,Any]:
        return self.chain[-1]

    # 整個(gè)區(qū)塊hash
    @staticmethod
    def hash(block:Dict[str,Any])->str:
        blockstring = json.dumps(block,sort_keys=True).encode()
        return hashlib.sha256(blockstring).hexdigest()

    # 不斷修改值,進(jìn)行hash碰撞,起到算出結(jié)果為止(即拿到證明)
    def proof_of_work(self,last_proof:int)->int:
        proof = 0
        while self.do_proof(last_proof,proof) is False:
            proof+=1
        return proof

    # 進(jìn)行hash碰撞
    @staticmethod
    def do_proof(last_proof:int,proof:int)->bool:
        guess=f'{last_proof*proof}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4]=="0000"#難度可調(diào)

    # 校驗(yàn)整個(gè)鏈?zhǔn)欠裾_
    def valid_chain(self,chain:List[Dict[str,Any]]):
        #用當(dāng)前區(qū)塊與前一個(gè)區(qū)塊進(jìn)行校驗(yàn),循環(huán)至最后一個(gè)
        pre_block = chain[0]
        current_index = 1
        while current_index<len(chain):
            block = chain[current_index]
            if block["pre_hash"]!=self.hash(pre_block): #校驗(yàn)是否被篡改,hash要能對上
                return False
            if not self.valid_proof(pre_block["proof"],block["proof"]):#校驗(yàn)工作量正確
                return False
            pre_block = block
            current_index+=1
        return True

    # 節(jié)點(diǎn)注冊,追加節(jié)點(diǎn)
    def register_node(self,addr:str)->None:
        now_url=urlparse(addr)#將addr轉(zhuǎn)成對象,能取出schame或port等
        self.nodes.add(now_url.path)#netloc='www.cwi.nl:80'

    #節(jié)點(diǎn)同步:查找所有的節(jié)點(diǎn),如果附近的節(jié)點(diǎn)比自己多,將鄰居節(jié)點(diǎn)的鏈賦值給自己節(jié)點(diǎn)
    def resolve_conflicts(self)->bool:
        neighbours=self.nodes
        new_chain=None
        max_length=len(self.chain)
        for node in neighbours:#從鄰居中取最長的鏈,賦值給new_chain
            response = requests.get(f"http://{node}/chain") #node的域名與端口都不一樣
            if response.status_code==200:
                length = response.json()["length"]
                chain = response.json()["chain"]
                if length > max_length :#and self.valid_chain(chain)
                    max_length = length
                    new_chain = chain
        if new_chain:
            self.chain = new_chain#將最長的鏈賦值給自己
            return True
        return False

niucoin = NiuCoinBlockChainTwo()
node_id = str(uuid4()).replace("-","")
print("當(dāng)前節(jié)點(diǎn)錢包地址:",node_id)

app = Flask(__name__)
@app.route("/")
def index_page():
    return "歡迎呵呵"

@app.route("/chain")
def chain():#輸出區(qū)塊鏈
    response={
        "chain":niucoin.chain,
        "length":len(niucoin.chain),
    }
    return jsonify(response),200

@app.route("/mine")#挖礦,系統(tǒng)獎(jiǎng)勵(lì)比特幣
def index_mine():
    last_block = niucoin.last_block()
    last_proof = last_block["proof"]
    proof = niucoin.proof_of_work(last_proof) #挖礦,挖到礦才往下走

    niucoin.new_transcations("0",node_id,200) #獲得獎(jiǎng)勵(lì)

    niucoin.new_block(None,proof)
    response={
        "message":"新的區(qū)塊產(chǎn)生",
        "index":niucoin.last_block()["index"],
        "transcations":niucoin.last_block()["transcations"],
        "proof":niucoin.last_block()["proof"],
        "pre_hash":niucoin.last_block()["pre_hash"]
    }

    return jsonify(response),200

@app.route("/new_transcations",methods=["POST"])#交易
def new_transcations():
    values = request.get_json()
    required = ["payer","recer","amount"]
    if not all(key in values for key in required):
        return "數(shù)據(jù)不完整",400
    index = niucoin.new_transcations(values["payer"],values["recer"],values["amount"])
    response = {
        "message":f"交易加入到區(qū)塊{index}"
    }
    return jsonify(response),200

@app.route("/new_node",methods=["POST"])
def new_node():
    values = request.get_json()
    nodes = values.get("nodes")#獲得所有節(jié)點(diǎn)
    if nodes is None:
        return "數(shù)據(jù)有問題",400
    for node in nodes:
        niucoin.register_node(node) #加入節(jié)點(diǎn)
    response = {
        "message":f"節(jié)點(diǎn)已經(jīng)追加",
        "node":list(niucoin.nodes)
    }
    return jsonify(response),200

@app.route("/node_refresh")
def node_refresh():
    replaced = niucoin.resolve_conflicts() #最長的鏈
    if replaced:
        response={
            "message":"區(qū)塊鏈查新為最長區(qū)塊鏈",
            "new_chain":niucoin.chain
        }
    else:
        response = {
            "message": "區(qū)塊鏈已經(jīng)是最長的,無需替換",
            "new_chain": niucoin.chain
        }
    return jsonify(response), 200

if __name__ == "__main__":
    app.run("127.0.0.1",port=65532)

NiuCoinBlockChainThree.py

# -*- coding: utf-8 -*-
from typing import Any,Dict,List,Optional
import time
import hashlib
from uuid import uuid4
import json
from flask import Flask
from flask import jsonify
from urllib.parse import urlparse
from flask import request
import requests

class NiuCoinBlockChainThree:

    #構(gòu)造器
    def __init__(self):
        self.current_transcations=[]#緩存交易列表,在沒有新區(qū)塊前放在這里,產(chǎn)生新區(qū)塊后,會(huì)被加入到新區(qū)塊
        self.chain=[]#區(qū)塊鏈管理多個(gè)區(qū)塊
        self.nodes=set()#保存網(wǎng)絡(luò)中的其它節(jié)點(diǎn)
        self.new_block(pre_hash="1",proof=100)#創(chuàng)世區(qū)塊

    #新增一個(gè)新區(qū)塊
    def new_block(self,pre_hash:Optional[str],proof:int)->Dict[str,Any]:
        block = {
            "index":len(self.chain)+1, #索引
            "timestamp":time.time(),
            "transcations":self.current_transcations,#將臨時(shí)緩存的交易放在區(qū)塊中
            "proof":proof,#工作量要記下來,校驗(yàn)區(qū)塊時(shí)需要這個(gè)證明
            "pre_hash":pre_hash or self.chain[-1]["hash"]
        }
        block["hash"] = self.hash(block)
        self.current_transcations=[]#交易被打包成區(qū)塊后,要清空
        self.chain.append(block)

    #新增一個(gè)新的交易
    def new_transcations(self,sender:str,recer:str,amount:int)->int:
        self.current_transcations.append({
            "sender":sender,
            "recer":recer,
            "amount":amount,
        })
        return self.last_block()["index"]+1

    # 獲得最后一個(gè)區(qū)塊
    def last_block(self)->Dict[str,Any]:
        return self.chain[-1]

    # 整個(gè)區(qū)塊hash
    @staticmethod
    def hash(block:Dict[str,Any])->str:
        blockstring = json.dumps(block,sort_keys=True).encode()
        return hashlib.sha256(blockstring).hexdigest()

    # 不斷修改值,進(jìn)行hash碰撞,起到算出結(jié)果為止(即拿到證明)
    def proof_of_work(self,last_proof:int)->int:
        proof = 0
        while self.do_proof(last_proof,proof) is False:
            proof+=1
        return proof

    # 進(jìn)行hash碰撞
    @staticmethod
    def do_proof(last_proof:int,proof:int)->bool:
        guess=f'{last_proof*proof}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4]=="0000"#難度可調(diào)

    # 校驗(yàn)整個(gè)鏈?zhǔn)欠裾_
    def valid_chain(self,chain:List[Dict[str,Any]]):
        #用當(dāng)前區(qū)塊與前一個(gè)區(qū)塊進(jìn)行校驗(yàn),循環(huán)至最后一個(gè)
        pre_block = chain[0]
        current_index = 1
        while current_index<len(chain):
            block = chain[current_index]
            if block["pre_hash"]!=self.hash(pre_block): #校驗(yàn)是否被篡改,hash要能對上
                return False
            if not self.valid_proof(pre_block["proof"],block["proof"]):#校驗(yàn)工作量正確
                return False
            pre_block = block
            current_index+=1
        return True

    # 節(jié)點(diǎn)注冊,追加節(jié)點(diǎn)
    def register_node(self,addr:str)->None:
        now_url=urlparse(addr)#將addr轉(zhuǎn)成對象,能取出schame或port等
        self.nodes.add(now_url.netloc)#netloc='www.cwi.nl:80'

    #節(jié)點(diǎn)同步:查找所有的節(jié)點(diǎn),如果附近的節(jié)點(diǎn)比自己多,將鄰居節(jié)點(diǎn)的鏈賦值給自己節(jié)點(diǎn)
    def resolve_conflicts(self)->bool:
        neighbours=self.nodes
        new_chain=None
        max_length=len(self.chain)
        for node in neighbours:#從鄰居中取最長的鏈,賦值給new_chain
            response = requests.get(f"http://{node}/chain") #node的域名與端口都不一樣
            if response.status_code==200:
                length = response.json()["length"]
                chain = response.json()["chain"]
                if length > max_length and self.valid_chain(chain):
                    max_length = length
                    new_chain = chain
        if new_chain:
            self.chain = new_chain#將最長的鏈賦值給自己
            return True
        return False

niucoin = NiuCoinBlockChainTwo()
node_id = str(uuid4()).replace("-","")
print("當(dāng)前節(jié)點(diǎn)錢包地址:",node_id)

app = Flask(__name__)
@app.route("/")
def index_page():
    return "歡迎呵呵"

@app.route("/chain")
def chain():#輸出區(qū)塊鏈
    response={
        "chain":niucoin.chain,
        "length":len(niucoin.chain),
    }
    return jsonify(response),200

@app.route("/mine")#挖礦,系統(tǒng)獎(jiǎng)勵(lì)比特幣
def index_mine():
    last_block = niucoin.last_block()
    last_proof = last_block["proof"]
    proof = niucoin.proof_of_work(last_proof) #挖礦,挖到礦才往下走

    niucoin.new_transcations("0",node_id,200) #獲得獎(jiǎng)勵(lì)

    niucoin.new_block(None,proof)
    response={
        "message":"新的區(qū)塊產(chǎn)生",
        "index":niucoin.last_block()["index"],
        "transcations":niucoin.last_block()["transcations"],
        "proof":niucoin.last_block()["proof"],
        "pre_hash":niucoin.last_block()["pre_hash"]
    }

    return jsonify(response),200

@app.route("/new_transcations",methods=["POST"])#交易
def new_transcations():
    values = request.get_json()
    required = ["payer","recer","amount"]
    if not all(key in values for key in required):
        return "數(shù)據(jù)不完整",400
    index = niucoin.new_transcations(values["payer"],values["recer"],values["amount"])
    response = {
        "message":f"交易加入到區(qū)塊{index}"
    }
    return jsonify(response),200

@app.route("/new_node",methods=["POST"])
def new_node():
    values = request.get_json()
    nodes = values.get("nodes")#獲得所有節(jié)點(diǎn)
    if nodes is None:
        return "數(shù)據(jù)有問題",400
    for node in nodes:
        niucoin.register_node(node) #加入節(jié)點(diǎn)
    response = {
        "message":f"節(jié)點(diǎn)已經(jīng)追加",
        "node":list(niucoin.nodes)
    }
    return jsonify(response),200

@app.route("/node_refresh")
def node_refresh():
    replaced = niucoin.resolve_conflicts() #最長的鏈
    if replaced:
        response={
            "message":"區(qū)塊鏈查新為最長區(qū)塊鏈",
            "new_chain":niucoin.chain
        }
    else:
        response = {
            "message": "區(qū)塊鏈已經(jīng)是最長的,無需替換",
            "new_chain": niucoin.chain
        }
    return jsonify(response), 200

if __name__ == "__main__":
    app.run("127.0.0.1",port=65533)

以上用到的庫(import),百度一下安裝即可;
端口要用5位,我這里四位不行,比如6000;
運(yùn)行時(shí)不要run flask,要配置python的運(yùn)行環(huán)境(在pycharm在右上角可配置flask還是python環(huán)境);
代碼比較長,先大概理解下代碼,跑完程序就理解所有代碼了;
有三個(gè)節(jié)點(diǎn)類,可以模擬三個(gè)節(jié)點(diǎn)信息同步,為了簡單我僅演示兩個(gè)。

1.準(zhǔn)備最長鏈,節(jié)點(diǎn)1

訪問『http://127.0.0.1:65531/mine』,執(zhí)行10次,制造最長鏈;
訪問『http://127.0.0.1:65531/chain』,可以顯示有11個(gè)區(qū)塊。

2.準(zhǔn)備短鏈,節(jié)點(diǎn)2

訪問『http://127.0.0.1:65532/mine』,執(zhí)行2次,制造最短鏈;
訪問『http://127.0.0.1:65532/chain』,可以顯示有3個(gè)區(qū)塊。

3.將所有節(jié)點(diǎn)注冊

用postman執(zhí)行『http://127.0.0.1:65532/new_node』,POST方式,內(nèi)容為『{"nodes":["127.0.0.1:65531","127.0.0.1:65533"]}』,加入節(jié)點(diǎn)1與節(jié)點(diǎn)3至節(jié)點(diǎn)2,這里僅是模擬,不要加入自己(節(jié)點(diǎn)2),否則會(huì)卡住線程。

4.同步信息,將短的替換為長的

訪問『http://127.0.0.1:65532/node_refresh』,同步最長鏈至當(dāng)前節(jié)點(diǎn);
至此就完成了簡單的節(jié)點(diǎn)間信息同步。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、快速術(shù)語檢索 比特幣地址:(例如:1DSrfJdB2AnWaFNgSbv3MZC2m74996JafV)由一串...
    不如假如閱讀 16,556評論 4 87
  • 不要再祈求那些一帆風(fēng)順的機(jī)會(huì)了 給你了,抓得住嗎 就算再來一次, 結(jié)果也不會(huì)變 配不上的終究會(huì)失去 你,還是你 嘿...
    小艾11號閱讀 308評論 0 0
  • 1做到了劃掉,只有一項(xiàng)沒做到,時(shí)間來不及,等下花點(diǎn)時(shí)間做到, 2.有哪些我覺得滿意的?自律,積極的完成態(tài)度,注意力...
    Hi_張閱讀 165評論 0 0
  • 這個(gè)月商場有活動(dòng),一元嗨購50元現(xiàn)金券,名額有限只有2000張,每人限購2張,可以疊加使用,使用時(shí)間3月17日開始...
    鎮(zhèn)江吾悅DDM徐冰閱讀 622評論 0 0
  • 大家做功能,遇到任務(wù)完成提醒的功能點(diǎn)時(shí),在界面顯示或者事件回調(diào)的地方調(diào)用下這個(gè)方法就可以,提示顯示的邏輯、控件的創(chuàng)...
    小母雞他哥閱讀 1,138評論 0 1

友情鏈接更多精彩內(nèi)容