diff --git a/Lesson-1/assignment/yours.sol b/Lesson-1/assignment/yours.sol index dfdb2c48..ea1b9978 100644 --- a/Lesson-1/assignment/yours.sol +++ b/Lesson-1/assignment/yours.sol @@ -1 +1,61 @@ /*作业请提交在这个目录下*/ +pragma solidity ^0.4.14; + +contract Payroll { + uint constant payDuration = 10 seconds; + + address owner; + uint salary; + address employee; + uint lastPayday; + + function Payroll() { + owner = msg.sender; + } + + //修改员工地址 + function changeEmployee(address e) { + //只有合约部署者才有权限改变员工地址 + require(msg.sender == owner); + + if (employee != 0x0) { //员工地址地址不能是0 + //发放未领取的工资 + uint payment = salary * (now - lastPayday) / payDuration; + employee.transfer(payment); + } + employee = e; + lastPayday = now; + } + + //更改跟员工薪水 + function changeSalary(uint money){ + //只有合约部署者才有权限改变员工薪水。money 默认参数是wei,需要转化。 + require(msg.sender==owner); + + salary = money * 1 ether; + + } + + + function addFund() payable returns (uint) { + return this.balance; + } + + function calculateRunway() returns (uint) { + return this.balance / salary; + } + + function hasEnoughFund() returns (bool) { + return calculateRunway() > 0; + } + + function getPaid() { + require(msg.sender == employee); + + uint nextPayday = lastPayday + payDuration; + assert(nextPayday < now); + + lastPayday = nextPayday; + employee.transfer(salary); + } +} diff --git a/Lesson-3/assignment/Ownable.sol b/Lesson-3/assignment/Ownable.sol new file mode 100644 index 00000000..a1efe5bb --- /dev/null +++ b/Lesson-3/assignment/Ownable.sol @@ -0,0 +1,42 @@ +pragma solidity ^0.4.18; + + +/** + * @title Ownable + * @dev The Ownable contract has an owner address, and provides basic authorization control + * functions, this simplifies the implementation of "user permissions". + */ +contract Ownable { + address public owner; + + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + + /** + * @dev The Ownable constructor sets the original `owner` of the contract to the sender + * account. + */ + function Ownable() public { + owner = msg.sender; + } + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + require(msg.sender == owner); + _; + } + + /** + * @dev Allows the current owner to transfer control of the contract to a newOwner. + * @param newOwner The address to transfer ownership to. + */ + function transferOwnership(address newOwner) public onlyOwner { + require(newOwner != address(0)); + OwnershipTransferred(owner, newOwner); + owner = newOwner; + } + +} diff --git a/Lesson-3/assignment/SafeMath.sol b/Lesson-3/assignment/SafeMath.sol new file mode 100644 index 00000000..d27c3cc5 --- /dev/null +++ b/Lesson-3/assignment/SafeMath.sol @@ -0,0 +1,47 @@ +pragma solidity ^0.4.18; + +/** + * @title SafeMath + * @dev Math operations with safety checks that throw on error + */ +library SafeMath { + + /** + * @dev Multiplies two numbers, throws on overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + if (a == 0) { + return 0; + } + uint256 c = a * b; + assert(c / a == b); + return c; + } + + /** + * @dev Integer division of two numbers, truncating the quotient. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + // assert(b > 0); // Solidity automatically throws when dividing by 0 + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + return c; + } + + /** + * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + assert(b <= a); + return a - b; + } + + /** + * @dev Adds two numbers, throws on overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + assert(c >= a); + return c; + } +} diff --git a/Lesson-3/assignment/addEmployee.jpeg b/Lesson-3/assignment/addEmployee.jpeg new file mode 100644 index 00000000..ef2f98ad Binary files /dev/null and b/Lesson-3/assignment/addEmployee.jpeg differ diff --git a/Lesson-3/assignment/addFun.jpeg b/Lesson-3/assignment/addFun.jpeg new file mode 100644 index 00000000..95e9ae83 Binary files /dev/null and b/Lesson-3/assignment/addFun.jpeg differ diff --git a/Lesson-3/assignment/caculateRunaway.jpeg b/Lesson-3/assignment/caculateRunaway.jpeg new file mode 100644 index 00000000..071d35ce Binary files /dev/null and b/Lesson-3/assignment/caculateRunaway.jpeg differ diff --git a/Lesson-3/assignment/checkEmployee.jpeg b/Lesson-3/assignment/checkEmployee.jpeg new file mode 100644 index 00000000..b7db1b6c Binary files /dev/null and b/Lesson-3/assignment/checkEmployee.jpeg differ diff --git a/Lesson-3/assignment/removeEmployee.jpeg b/Lesson-3/assignment/removeEmployee.jpeg new file mode 100644 index 00000000..ac5620f4 Binary files /dev/null and b/Lesson-3/assignment/removeEmployee.jpeg differ diff --git a/Lesson-3/assignment/transferOwnership.jpeg b/Lesson-3/assignment/transferOwnership.jpeg new file mode 100644 index 00000000..1bb166eb Binary files /dev/null and b/Lesson-3/assignment/transferOwnership.jpeg differ diff --git a/Lesson-3/assignment/yours.sol b/Lesson-3/assignment/yours.sol index dfdb2c48..e72ece24 100644 --- a/Lesson-3/assignment/yours.sol +++ b/Lesson-3/assignment/yours.sol @@ -1 +1,186 @@ /*作业请提交在这个目录下*/ + +pragma solidity ^0.4.21; + +import "./Ownable.sol"; +import "./SafeMath.sol"; + +contract Payroll is Ownable { + + using SafeMath for uint; + + struct Employee { + address id ; + uint salary ; + uint lastPayDay ; + } + + //Employee [] employees; + + mapping(address => Employee ) public employees; + + uint salary = 0 ether; + + //雇主 地址 + address owner = 0x0 ; + //员工地址 + // address employeeAddress = 0x0 ; + // 支付周期 + uint constant payDuration = 10 seconds ; + //上次支付时间 + uint lastPayDay = now; + + uint totalSalary; + + // modifier onlyOwner { + // require(msg.sender == owner); + // _; + // } + + modifier employeeExist(address employeeId) { + var employee = employees[employeeId]; + assert(employee.id != 0x0); + _; + } + + + modifier employeeNotExist(address employeeId) { + var employee = employees[employeeId]; + assert(employee.id == 0x0); + _; + } + + + + // init method + // function Payroll(){ + // owner = msg.sender; + // } + + // 支付 部分工资 + function _partialPay(Employee employee) private { + //assert(employee.id != 0x0); + uint payment = employee.salary.mul( now.sub( employee.lastPayDay ) ).div(payDuration) ; + employee.id.transfer(payment); + + } + + /* + function _findEmployee(address employeeId) private returns (Employee ,uint) { + for ( uint i= 0; i< employees.length ; i++ ){ + if ( employees[i].id == employeeId ) { + return ( employees[i] ,i); + } + } + }*/ + + function addEmployee( address employeeId, uint salary ) onlyOwner employeeNotExist(employeeId){ + // require(msg.sender == owner); + //Employee e =_findEmployee(employeeId); + // var (employee , index ) = employees[employeeId]; + var employee = employees[employeeId]; + //_findEmployee(employeeId); + // 异常 + // assert(employee.id == 0x0); + //employees.push(Employee(employeeId,salary * 1 ether,now)); + // totalSalary +=salary * 1 ether ; + + totalSalary = totalSalary.add(salary.mul(1 ether )); + + employees[employeeId]=Employee(employeeId,salary .mul(1 ether),now); + } + + function removeEmployee(address employeeId) onlyOwner employeeExist(employeeId) { + // require(msg.sender == owner); + + // var (employee , index ) = _findEmployee(employeeId); + var employee = employees[employeeId]; + // assert(employee.id != 0x0); + _partialPay(employee); + + + // totalSalary += employee.salary * 1 ether ; + totalSalary = totalSalary.sub(salary.mul(1 ether)); + delete employees[employeeId]; + + // employees[index] = employees[employees.length - 1]; + // employees.length -= 1; + + + } + + function updateEmployee(address employeeId,uint salary ) onlyOwner employeeExist(employeeId) { + // require(msg.sender == owner); + + // var (employee , index ) = _findEmployee(employeeId); + var employee = employees[employeeId]; + + totalSalary = totalSalary.sub(employee.salary).add(salary.mul(1 ether)); + + employees[employeeId].id = employeeId; + employees[employeeId].salary = salary.mul(1 ether); + employees[employeeId].lastPayDay = now; + + + } + + function addFund() payable returns (uint) { + // add money to contract + return this.balance ; + } + + function getFund () returns (uint) { + return this.balance ; + } + + function caculateRunaway() returns (uint){ + // uint totalSalary = 0; + + + // for ( uint i= 0; i< employees.length ; i++){ + // totalSalary += employees[i].salary ; + + // } + + assert(totalSalary !=0 ); + assert( this.balance !=0 ); + return this.balance.div(totalSalary) ; + } + + + + function hasEnoughFund() returns (bool) { + // return this.balance >= salary ; + // this 方法 gas 高 + return caculateRunaway()>0 ; + } + + function checkEmployee (address employeeId ) returns (uint salary ,uint lastPayDay ) { + var employee = employees[employeeId]; + // return (employee.salary ,employee.lastPayDay ); + salary = employee.salary ; + lastPayDay = employee.lastPayDay; + } + + function getPaid() employeeExist(msg.sender) { + var employee = employees[msg.sender]; + //var ( employee ,index) = _findEmployee(msg.sender); + + //assert( employee.id != 0x0 ); + + uint nexPayDay = lastPayDay.add( payDuration); + // 确保 支付时间 正确 + assert(nexPayDay < now); + /** + * if (nexPayDay > now ) { + revert() ; + exception no gas + } + */ + + lastPayDay = nexPayDay ; + // 发钱 + employee.id.transfer(employee.salary); + + } +}