悬赏合约在《百灵界》的设计中也算是个亮点啰!它可以实现悬赏的功能,有些类似于国内的威客,国外的freelancer这样的功能。不同的是,《百灵界》使用智能合约来完成这一功能。
如上图所示,悬赏主要分成三步,七个状态,由金主(发布悬赏的人)和猎人(应聘的人)来共同完成合约。智能合约没有第三方来监督这个过程,所以,悬赏的完成只能由金主和猎人之间的互信和博弈。设计了七个状态也是考虑到检视任务完成的复杂性,有一定的约束性,又让人有利益的驱动主动完成合约。
悬赏的功能不也正好对应当前的零工经济吗?! 撮合有需求的双方完成一定的任力,大家各取所需,不是皆大欢喜嘛!目前《百灵界》已上测试网,也想听听大家的意见,后期会不断改进。
pragma solidity >=0.4.22 <0.7.0;
pragma experimental ABIEncoderV2;
contract Bounty {
/*
金主发布悬赏 Created
金主取消任务 Cancelled
金主确认猎人 Confirmed
猎人A提交任务 HunterFinished
猎人A超时未提交任务 HunterOutOfTime
金主确认任务完成 Promoterfinished
金主超时未确认任务 PromoterOutOfTime
*/
enum State { Created, Cancelled, Confirmed, HunterFinished, HunterOutOfTime, Promoterfinished, PromoterOutOfTime}
uint public id = 0;
struct TaskMessage
{
string hash;
address promoter;
address hunterA;
address[] hunters;
string[] reasonHashs;
uint bonus;
uint taskStart;
uint taskDeadLine;
State state;
}
mapping(uint => TaskMessage) public tasks;
// receive() external payable { }
// fallback () external payable { }
modifier onlyPromoter(uint _uid) {
require(msg.sender == tasks[_uid].promoter);
_;
}
modifier onlyhunterA(uint _uid) {
require(msg.sender == tasks[_uid].hunterA);
_;
}
modifier inState(uint _uid, State _state) {
require(tasks[_uid].state == _state );
_;
}
modifier inTime(uint _uid) {
require(now <= tasks[_uid].taskStart + tasks[_uid].taskDeadLine);
_;
}
modifier outOfTime(uint _uid) {
require(now > tasks[_uid].taskStart + tasks[_uid].taskDeadLine);
_;
}
event SetTask(uint _uid, TaskMessage _task);
//金主发布悬赏。
function setTask(string memory _hash, uint _bonus, uint _hour, uint _minunt)
public
{
id += 1;
tasks[id].hash = _hash;
tasks[id].promoter = msg.sender;
tasks[id].bonus = _bonus;
tasks[id].taskDeadLine = _hour * 1 hours + _minunt * 1 minutes;
token.transferFromOrigin(address(this), _bonus+_bonus/2);
emit SetTask(id, tasks[id]);
}
//猎人申请任务
function applyTask(uint _uid, string memory _reasonHashs)
public
inState(_uid, State.Created)
{
require(tasks[_uid].promoter != msg.sender);
tasks[_uid].hunters.push(msg.sender);
tasks[_uid].reasonHashs.push(_reasonHashs);
}
//金主取消任务
function cancelTask(uint _uid)
public
inState(_uid, State.Created)
onlyPromoter(_uid)
{
token.transfer(msg.sender, tasks[_uid].bonus+tasks[_uid].bonus/2);
tasks[_uid].state = State.Cancelled;
}
//金主确认猎人A
function confirmHunter(uint _uid, address a)
public
inState(_uid, State.Created)
onlyPromoter(_uid)
{
tasks[_uid].hunterA = a;
tasks[_uid].taskStart = now;
tasks[_uid].state = State.Confirmed;
}
//猎人A提交任务
function hunterAFinished(uint _uid)
public
inTime(_uid)
inState(_uid, State.Confirmed)
onlyhunterA(_uid)
{
tasks[_uid].taskStart = now;
tasks[_uid].state = State.HunterFinished;
}
//猎人A超时未提交任务
function hunterAOutOfTime(uint _uid)
public
outOfTime(_uid)
onlyPromoter(_uid)
{
token.transfer(msg.sender, tasks[_uid].bonus+tasks[_uid].bonus/2);
tasks[_uid].state = State.HunterOutOfTime;
}
//金主确认任务完成
function promoterFinished(uint _uid)
public
inTime(_uid)
inState(_uid, State.HunterFinished)
onlyPromoter(_uid)
{
token.transfer(msg.sender, tasks[_uid].bonus/2);
token.transfer(tasks[_uid].hunterA, tasks[_uid].bonus);
tasks[_uid].state = State.Promoterfinished;
}
//金主退回任务
function taskFallback(uint _uid)
public
inTime(_uid)
inState(_uid, State.HunterFinished)
onlyPromoter(_uid)
{
tasks[_uid].taskStart = now;
tasks[_uid].state = State.Confirmed;
}
//金主超时未确认任务
function promoterOutOfTime(uint _uid)
public
outOfTime(_uid)
inState(_uid, State.HunterFinished)
onlyhunterA(_uid)
{
token.transfer(msg.sender, tasks[_uid].bonus);
tasks[_uid].state = State.PromoterOutOfTime;
}
//获取任务信息
function getTask(uint _uid)
public
view
returns (TaskMessage memory)
{
return (tasks[_uid]);
}
}
合约代码细节在这,有兴趣的可以参考。