solidity作为以太坊智能合约官方开发语言,紧随以太坊而诞生,由于是一门新语言,出于快速迭代中,版本更新很快,具体开发时,请参考文档。
下面介绍一个简单员工薪酬管理系统智能合约例子
pragma solidity ^0.4.14; // 注明版本
contract Payroll{
using SafeMath for uint; // uint 类型使用 safemath 库
// 结构体,类似C结构体,一个数据集合
struct Employee {
address id; // 员工地址
uint salary; // 薪水
uint lastPayday; // 支付时间
}
uint constant payDuration = 30 days; // 支付周期
uint totalSalary = 0;
// 映射表,使用方式 mapping(key => value) name;
mapping(address => Employee) public employees; // 员工列表
// modifier 代码段,类似内联函数,将冗余代码抽取出来,优化代码
modifier employeeExist(address employeeId) {
Employee employee = employees[employeeId];
require(employee.id != 0x0);
_; // 下划线表示代码段插入的位置,当前例子中,modifier代码插入方法体前
}
modifier employeeNotExist(address employeeId) {
Employee employee = employees[employeeId];
require(employee.id == 0x0);
_;
}
// 冗余关键代码段抽取为私有函数,注意智能合约涉及钱,函数权限一定要谨慎设定,solidity默认是public
function _partialPaid(Employee employee) private {
// sub、div 等方法是 safemath 方法,防止溢出风险
uint payments = now.sub(employee.lastPayday)
.div(payDuration)
.mul(employee.salary);
employee.id.transfer(payments);
}
/// 添加员工
function addEmployee(address employeeId, uint salaryEther) onlyOwner employeeNotExist(employeeId) {
uint salary = salaryEther.mul(1 ether);
employees[employeeId] = Employee(employeeId, salary, now);
totalSalary = totalSalary.add(salary);
}
/// 删除员工
function removeEmployee(address employeeId) onlyOwner employeeExist(employeeId) {
Employee memory employee= employees[employeeId];
delete employees[employeeId];
totalSalary = totalSalary.sub(employee.salary);
_partialPaid(employee);
}
/// 更新员工信息
function updateEmployee(address employeeId, uint salaryEther) onlyOwner employeeExist(employeeId) {
Employee memory employee= employees[employeeId];
uint salary = salaryEther.mul(1 ether);
totalSalary = totalSalary.add(salary).sub(employee.salary);
employees[employeeId].salary = salary;
employees[employeeId].lastPayday = now;
_partialPaid(employee);
}
/// 给资金池加钱
function addFund() payable returns (uint) {
return this.balance;
}
/// 计算可支付次数
function calculateRunway() returns (uint) {
return this.balance.div(totalSalary);
}
/// 是否够支付金额
function hasEnoughFund() returns (bool) {
return calculateRunway() > 0;
}
/// 获取工资
function getPaid() employeeExist(msg.sender){
Employee storage employee = employees[msg.sender];
uint nextPayday = employee.lastPayday.add(payDuration);
assert(nextPayday < now);
employees[msg.sender].lastPayday = nextPayday;
employee.id.transfer(employee.salary);
}
}
员工薪酬系统涉及到三个对象,员工,老板,钱,涉及的操作是对资源的增删改查,所有操作的权限应当是首先需要确认的,切记权限!!!