Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

9 张伟 - 第一次作业 #31

Merged
merged 55 commits into from
Jan 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
e695901
Create 测试
public2018 Dec 27, 2017
ca7f645
Create payroll.sol
Xuefeng-Zhu Jan 7, 2018
8d3f77d
Merge pull request #1 from linjie-1/master
Jan 7, 2018
e55edb6
update lesson folder
Jan 7, 2018
623e1ac
Merge pull request #12 from helloworldblockchain/master
Jan 7, 2018
3319fd5
Delete 软件测试1
Jan 7, 2018
3c04fea
Create yours.sol
Jan 7, 2018
ddc0fb1
Update yours.sol
Jan 7, 2018
76f556b
Create README.md
Jan 7, 2018
ee3a179
Create README.md
Jan 7, 2018
f0ae971
Update README.md
Jan 7, 2018
94e186c
Update README.md
Jan 7, 2018
875e149
Create README.md
Jan 7, 2018
c29a23e
Update README.md
Jan 7, 2018
2c0b136
Update README.md
Jan 7, 2018
55e7427
Update README.md
Jan 7, 2018
251bd4f
Update README.md
Jan 7, 2018
17ceaa5
Update README.md
Jan 7, 2018
dd09e78
Update README.md
linjie-1 Jan 7, 2018
a89e214
Update README.md
linjie-1 Jan 7, 2018
c794e3c
Update and rename lesson1/README.md to 2014/07/23/README.md
linjie-1 Jan 7, 2018
b2d1bd2
changshi xiugai master
Crapulencer Jan 7, 2018
047ed69
chexiaocaozuo
Crapulencer Jan 7, 2018
b777a5f
Rename 2014/07/23/README.md to lesson1/README.md
Jan 7, 2018
72f8050
Merge remote-tracking branch 'linjie-1/master'
Jan 7, 2018
0a715c3
Add setter for salary and wallet
Jan 8, 2018
d2a8fa5
Merge pull request #32 from public2018/master
public2018 Jan 8, 2018
d2c795d
Update README.md
linjie-1 Jan 8, 2018
040a107
Update README.md
linjie-1 Jan 8, 2018
b3be527
Update README.md
linjie-1 Jan 8, 2018
f06e298
Update README.md
linjie-1 Jan 8, 2018
36dd3f1
Update README.md
Jan 8, 2018
3dd59ce
Update README.md
Jan 8, 2018
293161a
Update README.md
linjie-1 Jan 8, 2018
81bd092
Delete 测试
Jan 8, 2018
e4e5383
将课程表的图片替换成markdown实现
lsdlinshunda Jan 8, 2018
1d31ebb
Update README.md
linjie-1 Jan 10, 2018
d64d000
Update README.md
linjie-1 Jan 10, 2018
c30b7c5
Update README.md
linjie-1 Jan 10, 2018
b8802e3
Update README.md
linjie-1 Jan 10, 2018
46f2a72
Create README.md
linjie-1 Jan 10, 2018
b6414d5
Create README.md
linjie-1 Jan 10, 2018
6a024e5
Update README.md
linjie-1 Jan 10, 2018
1452883
Create README.md
linjie-1 Jan 10, 2018
2b8da80
Update README.md
linjie-1 Jan 10, 2018
f98dcab
Create yours.sol
linjie-1 Jan 10, 2018
529ef5a
Update README.md
linjie-1 Jan 10, 2018
39b2136
Delete yours.sol
linjie-1 Jan 10, 2018
a298b92
Create yours.sol
linjie-1 Jan 10, 2018
65f8dc3
Delete yours.sol
linjie-1 Jan 10, 2018
758a324
Create yours.sol
lsdlinshunda Jan 10, 2018
5483f5e
lesson 2
modong Jan 10, 2018
3af7f4f
调整课程表中课程更新时间
lsdlinshunda Jan 10, 2018
9f32abc
Merge remote-tracking branch 'linjie-1/master'
Jan 12, 2018
caa3ffd
第二次作业
Jan 14, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Lesson2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## 硅谷live以太坊智能合约频道官方地址

### 第二课《智能合约设计进阶-多员工薪酬系统》

目录结构
<br/>|
<br/>|--orgin 课程初始代码
<br/>|
<br/>|--assignment 课程作业提交代码
<br/>
### 本节知识点
第2课:智能合约设计进阶-多员工薪酬系统
- 动态静态数组的不同
- 函数输入参数检查 revert
- 循环与遍历的安全性
- 程序运行错误检查和容错:assert与require
10 changes: 10 additions & 0 deletions Lesson2/assignment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## 硅谷live以太坊智能合约 第二课作业
这里是同学提交作业的目录

### 第二课:课后作业
完成今天的智能合约添加100ETH到合约中
- 加入十个员工,每个员工的薪水都是1ETH
每次加入一个员工后调用calculateRunway这个函数,并且记录消耗的gas是多少?Gas变化么?如果有 为什么?
- 如何优化calculateRunway这个函数来减少gas的消耗?
提交:智能合约代码,gas变化的记录,calculateRunway函数的优化

282 changes: 282 additions & 0 deletions Lesson2/assignment/yours.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
pragma solidity ^0.4.14;

/** @title Payroll contract. */
contract Payroll {
struct Employee {
address wallet;
uint salary;
uint lastPayday;
}

Employee[] employees;
address owner;
uint constant payDuration = 10 seconds;

/** @dev Constructor.
*/
function Payroll() {
owner = msg.sender;
}

/** @dev Pay employee their rest payment before any change.
* @param employee Employee that need to be paid.
*/
function _payRestSalary(Employee employee) private {
uint restPayment = employee.salary * (now - employee.lastPayday) / payDuration;
employee.wallet.transfer(restPayment);
}

/** @dev Find target employee in employee array.
* @param targetWallet Wallet address of the target employee.
*/
function _findEmployee(address targetWallet) private returns (Employee, uint) {
for (uint i=0; i<employees.length; i++) {
if (employees[i].wallet == targetWallet) {
return (employees[i], i);
}
}
}

/** @dev Add new employee to contract.
* @param salary Salary of the new employee.
* @param wallet Wallet address of the new employee.
*/
function addEmployee(uint salary, address wallet) {
require(msg.sender == owner);

var (employee,index) = _findEmployee(wallet);
assert(employee.wallet == 0x0);

employees.push(Employee(wallet, salary * 1 ether, now));
}

/** @dev Remove new employee in the contract.
* @param salary Salary of the new employee needs to be updated.
* @param wallet Wallet address of the employee needs to be updated.
*/
function updateEmployee(uint salary, address wallet) {
require(msg.sender == owner);
var (employee, index) = _findEmployee(wallet);
assert(employee.wallet != 0x0);

_payRestSalary(employees[index]);
employees[index].salary = salary;
employees[index].lastPayday = now;
}

/** @dev Update employee in the contract.
* @param wallet Wallet address of the employee needs to be removed.
*/
function removeEmployee(address wallet) {
require(msg.sender == owner);
var (employee, index) = _findEmployee(wallet);
assert(employee.wallet != 0x0);

_payRestSalary(employees[index]);
employees[index] = employees[employees.length-1];
employees.length-1;
}

/** @dev add fund to employer.
* @return employer balance after adding fund.
*/
function addFund() payable returns (uint) {
return this.balance;
}

/** @dev calculate how many times the employer can pay the employees
* @return the times that employees can get paid from employer's balance
*/
function calculateRunway() returns (uint) {
uint totalSalary = 0;
for (uint i=0; i<employees.length; i++) {
totalSalary += employees[i].salary;
}
return this.balance / totalSalary;
}

/** @dev check if employer has enough money to pay
* @return true means employers has enough money, false means not
*/
function hasEnoughFund() returns (bool) {
return calculateRunway() > 0;
}

/** @dev pay salary to employee
*/
function getPaid() {
var (employee, index) = _findEmployee(msg.sender);
assert(employee.wallet == 0x0);

uint nextPayDay = employee.lastPayday + payDuration;
if (nextPayDay > now) {
revert();
}

employees[index].lastPayday = nextPayDay;
employees[index].wallet.transfer(employee.salary);
}
}

//gas history
0xca35b7d915458ef540ade6068dfe2f44e8fa733c
transaction cost 23009 gas
execution cost 1737 gas

0x14723a09acff6d2a60dcdf7aa4aff308fddc160c
transaction cost 23779 gas
execution cost 2507 gas

0x583031d1113ad414f02576bd6afabfb302140225
transaction cost 24549 gas
execution cost 3277 gas

0xdd870fa1b7c4700f2bd7f44238821c26f7392148
transaction cost 25319 gas
execution cost 4047 gas

//transaction cost 和 execution cost都在逐渐提升

//原因:我认为是因为Employee数组中的员工数量递增,使得for循环次数增加,导致计算成本加大,从而gas cost升高。

//优化:不必每次调用calculateRunway都调用for循环来计算totalSalary,可以在每次添加新员工是进行计算,还要在更新员工信息的时候进行更新。
//优化代码
pragma solidity ^0.4.14;

/** @title Payroll contract. */
contract Payroll {
struct Employee {
address wallet;
uint salary;
uint lastPayday;
}

Employee[] employees;
address owner;
uint totalSalary = 0;
uint constant payDuration = 10 seconds;

/** @dev Constructor.
*/
function Payroll() {
owner = msg.sender;
}

/** @dev Pay employee their rest payment before any change.
* @param employee Employee that need to be paid.
*/
function _payRestSalary(Employee employee) private {
uint restPayment = employee.salary * (now - employee.lastPayday) / payDuration;
employee.wallet.transfer(restPayment);
}

/** @dev Find target employee in employee array.
* @param targetWallet Wallet address of the target employee.
*/
function _findEmployee(address targetWallet) private returns (Employee, uint) {
for (uint i=0; i<employees.length; i++) {
if (employees[i].wallet == targetWallet) {
return (employees[i], i);
}
}
}

/** @dev Add new employee to contract.
* @param salary Salary of the new employee.
* @param wallet Wallet address of the new employee.
*/
function addEmployee(uint salary, address wallet) {
require(msg.sender == owner);

var (employee,index) = _findEmployee(wallet);
assert(employee.wallet == 0x0);

employees.push(Employee(wallet, salary * 1 ether, now));
totalSalary += salary * 1 ether;
}

/** @dev Remove new employee in the contract.
* @param salary Salary of the new employee needs to be updated.
* @param wallet Wallet address of the employee needs to be updated.
*/
function updateEmployee(uint salary, address wallet) {
require(msg.sender == owner);
var (employee, index) = _findEmployee(wallet);
assert(employee.wallet != 0x0);

_payRestSalary(employees[index]);
totalSalary = totalSalary - employees[index].salary;
employees[index].salary = salary * 1 ether;
totalSalary = totalSalary + salary;

employees[index].lastPayday = now;
}

/** @dev Update employee in the contract.
* @param wallet Wallet address of the employee needs to be removed.
*/
function removeEmployee(address wallet) {
require(msg.sender == owner);
var (employee, index) = _findEmployee(wallet);
assert(employee.wallet != 0x0);

_payRestSalary(employees[index]);
employees[index] = employees[employees.length-1];
employees.length-1;
}

/** @dev add fund to employer.
* @return employer balance after adding fund.
*/
function addFund() payable returns (uint) {
return this.balance;
}

/** @dev calculate how many times the employer can pay the employees
* @return the times that employees can get paid from employer's balance
*/
function calculateRunway() returns (uint) {
return this.balance / totalSalary;
}

/** @dev check if employer has enough money to pay
* @return true means employers has enough money, false means not
*/
function hasEnoughFund() returns (bool) {
return calculateRunway() > 0;
}

/** @dev pay salary to employee
*/
function getPaid() {
var (employee, index) = _findEmployee(msg.sender);
assert(employee.wallet == 0x0);

uint nextPayDay = employee.lastPayday + payDuration;
if (nextPayDay > now) {
revert();
}

employees[index].lastPayday = nextPayDay;
employees[index].wallet.transfer(employee.salary);
}
}

//new gas history
0xca35b7d915458ef540ade6068dfe2f44e8fa733c
transaction cost 125490 gas
execution cost 102618 gas

0x14723a09acff6d2a60dcdf7aa4aff308fddc160c
transaction cost 22202 gas
execution cost 930 gas

0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db
transaction cost 22202 gas
execution cost 930 gas

0x583031d1113ad414f02576bd6afabfb302140225
transaction cost 22202 gas
execution cost 930 gas

//gas 不变了,因为calculateRunway现在只是做一个除法
3 changes: 3 additions & 0 deletions Lesson2/orgin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 硅谷live以太坊智能合约 第二课《智能合约设计进阶-多员工薪酬系统》

这里是每一课的初始代码,有需要的同学可以参考
50 changes: 50 additions & 0 deletions Lesson2/orgin/payroll.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
pragma solidity ^0.4.14;

contract Payroll {
struct Employee {
address id;
uint salary;
uint lastPayday;
}

uint constant payDuration = 10 seconds;

address owner;
Employee[] employees;

function Payroll() {
owner = msg.sender;
}

function _partialPaid(Employee employee) private {
}

function _findEmployee(address employeeId) private returns (Employee, uint) {
}

function addEmployee(address employeeId, uint salary) {
}

function removeEmployee(address employeeId) {
}

function updateEmployee(address employeeId, uint salary) {
}

function addFund() payable returns (uint) {
}

function calculateRunway() returns (uint) {
uint totalSalary = 0;
for (uint i = 0; i < employees.length; i++) {
totalSalary += employees[i].salary;
}
return this.balance / totalSalary;
}

function hasEnoughFund() returns (bool) {
}

function getPaid() {
}
}
Loading