import "loadResource.yjs" @LogType("Arg") contract Incentives{ export function getMainFrame(arg){ return "/html/main.html"; } function onCreate(arg) { Global.owner = requester; Global.bids = []; Global.asks = []; Global.listFinal = []; Global.status = "Bidding"; } export function getOwner(arg) { return Global.owner; } export function isOwner(arg) { return requester==Global.owner; } export function getStatus(arg) { return Global.status; } export function getAskListRW(arg) { var retList = []; for (var i = 0; i < Global.asks.length; i++) { var ask = {}; ask["item"] = Global.asks[i]["item"]; if (Global.asks[i]["seller"] == requester) { ask["seller"] = Global.asks[i]["seller"]; ask["price"] = Global.asks[i]["price"]; } else { ask["seller"] = "Anonymous"; ask["price"] = "Unknown"; } retList.push(ask); } return JSON.stringify(retList); } export function getAskListRO(arg) { if (requester != Global.owner) { return "Access Denied"; } return JSON.stringify(Global.asks); } export function getBidListAll(arg) { if (requester != Global.owner) { return "Access Denied"; } return JSON.stringify(Global.bids); } export function getBidListPrivate(arg) { var retList = []; for (var i = 0; i < Global.bids.length; i++) { if (Global.bids[i]["bidder"]==requester) { retList.push(Global.bids[i]); } } return JSON.stringify(retList); } export function bid(arg) {//每个args的格式是:{"bidder":"","item":""} item资源编号,bidder买方 var args = JSON.parse(arg); args["bidder"] = requester; //从外界引入bidder的编号 return bidHelper(args); } function bidHelper(args){ if (Global.status != "Bidding") { return "Not in bidding status!"; } var asks = findAllElements(Global.asks, "item", args["item"]); if (asks.length == 0) { return "No such item exists!"; } for (var i = 0; i< Global.bids.length; i++) { if (Global.bids[i]["bidder"]==args["bidder"] && Global.bids[i]["item"]==args["item"]) { return "A valid bid already exists"; //这个已经存在买方购买该资源的信息 } } Global.bids.push(args); //没有已存在,就可以将这个信息加入global.bids return "Success"; } export function ask(arg) { //每个args的格式是:{"seller":"","item":""} item资源编号,seller卖方 var args = JSON.parse(arg); args["seller"] = requester; return askHelper(args); } function askHelper(args){ if (Global.status != "Bidding") { return "Not in bidding status"; } for (var i = 0; i< Global.asks.length; i++) { if (Global.asks[i]["item"]==args["item"]) { return "A valid ask already exists"; //已经存在卖方提供该资源的信息 } } Global.asks.push(args); //没有已存在,就可以将这个信息加入Global.asks return "Success"; } export function match(arg) { if (Global.status != "Bidding") { return "Not in bidding status"; } if (requester != Global.owner) { return "Access Denied"; } if (Global.bids.length == 0 || Global.asks.length == 0) { return "Must have at least 1 resource and 1 bid!"; } // Algorithm 2 winning candidates determination // sort bids and asks sortObjectArray(Global.bids,"price",false); //买方按照价格降序跑列 sortObjectArray(Global.asks,"price",true); //卖方升序排列 // calculate threshold value var thrPos = Math.ceil((Global.asks.length+1.0)/2.0); //取中位数beta var askThrValue = Global.asks[thrPos-1]["price"]; //卖方的阈值 // get candidates according to the threshold value var candidateBidsTmp = []; for (var i = 0; i < Global.bids.length; i++) { if (Global.bids[i]["price"] >= askThrValue) { //取大于等于卖方阈值的所有买方价格 candidateBidsTmp.push(Global.bids[i]); //candidateBidsTmp:大于等于卖方阈值价格的买方价格 } else { break; } } var bidThrValue = candidateBidsTmp[candidateBidsTmp.length-1]["price"]; //取买方的阈值最低价 // get rid of impossible candidates踢出不可能的candidates var candidateAsks = []; var candidateBids = []; for (var i=0; i maxU) { maxU = utilities[j]; maxUIndex = j; } } listFinal.push(matches[maxUIndex]); } } Global.listFinal = listFinal; Global.status = "Finalized"; return "Success"; } @Cost({"countGas":true,"extraGas":"getFinalPrice"}) export function execute(arg) { if (Global.status != "Finalized") { return "Bidding has not been finalized!" } var args = JSON.parse(arg); var winningBid = false; for (var i=0; i < Global.listFinal.length; i++) { if (Global.listFinal[i]["used"]) { continue; } if (Global.listFinal[i]["item"]==args["item"] && Global.listFinal[i]["bidder"]==requester) { winningBid = true; Global.listFinal[i]["used"] = true; Global.listFinal[i]["result"] = "Success"; break; } } if (!winningBid) { return "Access Denied"; } print(args["item"] + " used by " + requester); return "Success"; } export function getFinalPrice(arg) { var args = JSON.parse(arg); var winningPrice = 0; for (var i=0; i < Global.listFinal.length; i++) { if (Global.listFinal[i]["item"]==args["item"] && Global.listFinal[i]["bidder"]==requester) { winningPrice = Global.listFinal[i]["bidderPrice"]; break; } } return winningPrice; } export function resetStatus(arg) { if (requester != Global.owner) { return "Access Denied" } Global.bids = []; Global.asks = []; Global.listFinal = []; Global.status = "Bidding"; return "Success"; } function sortObjectArray(arr, prop, isAsc) { //数组arr按照属性prp的值升序/降序排列 if (isAsc) { for (var a=0; a < arr.length; a++) { for (var b=0; b < arr.length-1-a; b++) { if (arr[b][prop] > arr[b+1][prop]) { var tmp = arr[b]; arr[b] = arr[b+1]; arr[b+1] = tmp; } } } } else { for (var a=0; a < arr.length; a++) { for (var b=0; b < arr.length-1-a; b++) { if (arr[b][prop] < arr[b+1][prop]) { var tmp = arr[b]; arr[b] = arr[b+1]; arr[b+1] = tmp; } } } } return arr; } function findAllElements(arr, prop, value) { //找到arr的prop属性等于value的所有元素 var newArr = []; for (var a = 0; a < arr.length; a++) { if (arr[a][prop] == value) { newArr.push(arr[a]); } } return newArr; } export function getFinalListOwner(arg) { if (requester != Global.owner) { return "Access Denied"; } var retList = []; for (var i = 0; i < Global.listFinal.length; i++) { var fin = {}; fin["item"] = Global.listFinal[i]["item"]; fin["seller"] = Global.listFinal[i]["seller"]; fin["bidder"] = Global.listFinal[i]["bidder"]; fin["sellerPrice"] = Global.listFinal[i]["sellerPrice"]; fin["bidderPrice"] = Global.listFinal[i]["bidderPrice"]; fin["used"] = Global.listFinal[i]["used"]; fin["result"] = "Unknown"; retList.push(fin); } return JSON.stringify(retList); } export function getFinalListPrivate(arg) { var retList = []; for (var i = 0; i < Global.listFinal.length; i++) { var fin = {}; fin["item"] = Global.listFinal[i]["item"]; fin["used"] = Global.listFinal[i]["used"]; if (Global.bids[i]["bidder"]==requester && Global.bids[i]["seller"]==requester) { fin["seller"] = Global.listFinal[i]["seller"]; fin["bidder"] = Global.listFinal[i]["bidder"]; fin["sellerPrice"] = Global.listFinal[i]["sellerPrice"]; fin["bidderPrice"] = Global.listFinal[i]["bidderPrice"]; fin["result"] = Global.listFinal[i]["result"]; fin["canExecute"] = true; retList.push(fin); fin["result"] = Global.listFinal[i]["result"]; } else if (Global.bids[i]["bidder"]==requester) { fin["seller"] = "Anonymous"; fin["bidder"] = Global.listFinal[i]["bidder"]; fin["sellerPrice"] = "Unknown"; fin["bidderPrice"] = Global.listFinal[i]["bidderPrice"]; fin["result"] = Global.listFinal[i]["result"]; fin["canExecute"] = true; retList.push(fin); } else if (Global.bids[i]["seller"]==requester) { fin["seller"] = Global.listFinal[i]["seller"]; fin["bidder"] = "Anonymous"; fin["sellerPrice"] = Global.listFinal[i]["sellerPrice"]; fin["bidderPrice"] = "Unknown"; fin["result"] = "Unknown"; fin["canExecute"] = false; retList.push(fin); } } return JSON.stringify(retList); } }