以太坊智能合約投票樣本Java類比實現

來源:互聯網
上載者:User

使用java語言類比實現以太坊智能合約執行過程

package contract;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.List;import java.util.Map;/** * Created by haibiao on 2018/1/5. */public class BallotContract {    private static final String TAG = "BallotContract";    /**身份審核(賦予投票權)截止時間*/    public static final long VERIFY_DEADLINE = 1515168000000L;//2018/01/06 00:00:00.000    /**投票(委託)截止時間*/    public static final long VOTE_DEADLINE = VERIFY_DEADLINE + (1000 * 60 * 2);//身份審核結束後的2分鐘內為投票時間    /**合約單一實例*/    private static BallotContract INSTANCE;    /**合約建立者(投票主持人)地址*/    private final String mChairAddress;    /**投票者狀態儲存*/    private final Map<String,Voter> mVoterMap = new HashMap<>();    /**提案列表*/    private final Proposal[] mProposals;    /**投票結果,得票數最多的提案索引*/    private int[] mVoteResult;    /**每次調用合約都會包含的上下文*/    private Ctx ctx;    /**     * 建立合約,只會執行一次     * @param ctx 調用時的上下文     * @param names 提案名稱數組     */    public static void create(Ctx ctx,String[] names){        if(INSTANCE == null){            INSTANCE = new BallotContract(ctx,names);        }    }    /**     * 擷取合約執行個體     * @param ctx 調用時的上下文     * @return 投票合約執行個體     */    public static BallotContract getDefault(Ctx ctx){        INSTANCE.ctx = ctx;        return INSTANCE;    }    /**     * 投票合約建構函式,初始化一些變數     * @param ctx 上下文     * @param names 提案名稱數組     */    private BallotContract(Ctx ctx, String[] names) {        mChairAddress = ctx.msg.sender;        Voter chair = new Voter();        chair.weight = 1;        mVoterMap.put(mChairAddress,chair);        mProposals = new Proposal[names.length];        for(int i = 0 ; i < mProposals.length ; i++){            mProposals[i] = new Proposal();            mProposals[i].name = names[i];        }    }    /**     * 擷取投票結果,只有當投票階段結束且調用了一次統票方法才會有值     * @return 投票結果     */    public int[] getVoteResult(){        return mVoteResult;    }    /**     * 賦予投票權,只能主持人調用     * @param address 賦予的目標地址     * @return 賦予投票權結果     */    public boolean giveVoteRight(String address){        if(System.currentTimeMillis() > VERIFY_DEADLINE){            log("giveVoteRight time already over");            return false;        }        if(!mChairAddress.equals(ctx.msg.sender)){            log("giveVoteRight only the chairman can call");            return false;        }        Voter voter = mVoterMap.get(address);        if(voter == null){            voter = new Voter();            voter.weight = 1;            mVoterMap.put(address,voter);            log("giveVoteRight success , address = " + address);            return true;        }else{            log("giveVoteRight failed , yet give,address = "+address);        }        return false;    }    /**     * 委託操作,將投票權委託給他人     * @param to 受託人地址     * @return 委託結果     */    public boolean delegate(final String to){        final long curr = System.currentTimeMillis();        if(curr <= VERIFY_DEADLINE){            log("delegate failed,The delegate hasn't begun");            return false;        }        if(curr > VOTE_DEADLINE){            log("delegate failed,delegate already over ");            return false;        }        final String sender = ctx.msg.sender;        Voter fromVoter = mVoterMap.get(sender);        if(fromVoter == null //沒有投票權                || fromVoter.weight <= 0 //沒有投票權                || sender.equals(to) //委託給自己                ){            log("delegate failed");            return false;        }        String toTemp = to;        Voter toVoter = null;        while (true){            toVoter = mVoterMap.get(toTemp);            if(toVoter == null//受託人沒有投票權                    || toVoter.weight <= 0 //受託人沒有投票權                    ){                return false;            }            if(toVoter.delegate == null){                toVoter.weight += fromVoter.weight;                fromVoter.weight = 0;                fromVoter.delegate = toTemp;                return true;            }else{                toTemp = toVoter.delegate;            }        }    }    /**     * 執行投票     * @param index 提案的索引     * @return 投票結果     */    public boolean vote(int index){        final long curr = System.currentTimeMillis();        if(curr <= VERIFY_DEADLINE){            log("vote failed,The delegate hasn't begun");            return false;        }        if(curr > VOTE_DEADLINE){            log("vote failed,vote already over");            return false;        }        if(index < 0 || index >= mProposals.length){            log("proposal index error , index = "+index);            return false;        }        final String sender = ctx.msg.sender;        Voter voter = mVoterMap.get(sender);        if(voter == null //沒有投票權                || voter.weight <= 0 //沒有投票權                ){            log("vote failed");            return false;        }        final Proposal proposal = mProposals[index];        proposal.voteCount += voter.weight;        voter.weight = 0;        voter.proposalIndex = index;        return true;    }    /**     * 統計票數,任何人都可以隨時調用,當投票階段結束後,調用此方法會將會儲存最終的投票結果     * @return 當前統票結果     */    public int[] statisticsVote(){        if(System.currentTimeMillis() <= VERIFY_DEADLINE){            log("The statistics vote hasn't begun");            return new int[0];        }        final List<Integer> result = new ArrayList<>(1);        int maxCount = -1;        for(int i = 0 ; i < mProposals.length ; i++){            int count = mProposals[i].voteCount;            if(count > maxCount){                maxCount = count;                result.clear();                result.add(i);            }else if(count == maxCount){                result.add(i);            }        }        int[] arr = new int[result.size()];        for(int i = 0 ; i < arr.length ; i++){            arr[i] = result.get(i);        }        if(System.currentTimeMillis() > VOTE_DEADLINE){            //投票階段已結束,儲存統票結果            mVoteResult = arr;        }        log("statistics vote result = "+ Arrays.toString(arr));        return arr;    }    private static void log(String msg){        System.out.println(String.format("[%s]%s",TAG,msg));    }    /**     * 投票者資料結構     */    private static class Voter{        int weight;//票數        String delegate;//受託者        int proposalIndex;//提案索引號    }    /**     * 提案資料結構     */    private static class Proposal{        String name;//提案名稱        int voteCount;//提案所得票數    }}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.