diff --git a/Lesson-2/README.md b/Lesson-2/README.md
new file mode 100644
index 00000000..1fdc5b30
--- /dev/null
+++ b/Lesson-2/README.md
@@ -0,0 +1,16 @@
+## 硅谷live以太坊智能合约频道官方地址
+
+### 第二课《智能合约设计进阶-多员工薪酬系统》
+
+目录结构
+
|
+
|--orgin 课程初始代码
+
|
+
|--assignment 课程作业提交代码
+
+### 本节知识点
+第2课:智能合约设计进阶-多员工薪酬系统
+- 动态静态数组的不同
+- 函数输入参数检查 revert
+- 循环与遍历的安全性
+- 程序运行错误检查和容错:assert与require
diff --git a/Lesson-2/assignment/README.md b/Lesson-2/assignment/README.md
new file mode 100644
index 00000000..a1fa2d04
--- /dev/null
+++ b/Lesson-2/assignment/README.md
@@ -0,0 +1,10 @@
+## 硅谷live以太坊智能合约 第二课作业
+这里是同学提交作业的目录
+
+### 第二课:课后作业
+完成今天的智能合约添加100ETH到合约中
+- 加入十个员工,每个员工的薪水都是1ETH
+每次加入一个员工后调用calculateRunway这个函数,并且记录消耗的gas是多少?Gas变化么?如果有 为什么?
+- 如何优化calculateRunway这个函数来减少gas的消耗?
+提交:智能合约代码,gas变化的记录,calculateRunway函数的优化
+
diff --git a/Lesson-2/assignment/yours.sol b/Lesson-2/assignment/yours.sol
new file mode 100644
index 00000000..dfdb2c48
--- /dev/null
+++ b/Lesson-2/assignment/yours.sol
@@ -0,0 +1 @@
+/*作业请提交在这个目录下*/
diff --git a/Lesson-2/orgin/README.md b/Lesson-2/orgin/README.md
new file mode 100644
index 00000000..0309d947
--- /dev/null
+++ b/Lesson-2/orgin/README.md
@@ -0,0 +1,3 @@
+## 硅谷live以太坊智能合约 第二课《智能合约设计进阶-多员工薪酬系统》
+
+这里是每一课的初始代码,有需要的同学可以参考
diff --git a/Lesson-2/orgin/payroll.sol b/Lesson-2/orgin/payroll.sol
new file mode 100644
index 00000000..62e380e4
--- /dev/null
+++ b/Lesson-2/orgin/payroll.sol
@@ -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() {
+ }
+}
diff --git a/Lesson-3/README.md b/Lesson-3/README.md
new file mode 100644
index 00000000..ba26ced6
--- /dev/null
+++ b/Lesson-3/README.md
@@ -0,0 +1,16 @@
+## 硅谷live以太坊智能合约频道官方地址
+
+### 第三课《智能合约后端优化和产品化》
+
+目录结构
+
|
+
|--orgin 课程初始代码
+
|
+
|--assignment 课程作业提交代码
+
+### 本节知识点
+第3课:智能合约后端优化和产品化
+- 如何通过数据结构优化降低合约执行成本
+- 合约的继承
+- 巧用modifier
+- 以太坊函数库的使用和基本介绍
diff --git a/Lesson-3/assignment/README.md b/Lesson-3/assignment/README.md
new file mode 100644
index 00000000..01011eb4
--- /dev/null
+++ b/Lesson-3/assignment/README.md
@@ -0,0 +1,14 @@
+## 硅谷live以太坊智能合约 第三课作业
+这里是同学提交作业的目录
+
+### 第三课:课后作业
+- 第一题:完成今天所开发的合约产品化内容,使用Remix调用每一个函数,提交函数调用截图
+- 第二题:增加 changePaymentAddress 函数,更改员工的薪水支付地址,思考一下能否使用modifier整合某个功能
+- 第三题(加分题):自学C3 Linearization, 求以下 contract Z 的继承线
+- contract O
+- contract A is O
+- contract B is O
+- contract C is O
+- contract K1 is A, B
+- contract K2 is A, C
+- contract Z is K1, K2
diff --git a/Lesson-3/assignment/yours.sol b/Lesson-3/assignment/yours.sol
new file mode 100644
index 00000000..dfdb2c48
--- /dev/null
+++ b/Lesson-3/assignment/yours.sol
@@ -0,0 +1 @@
+/*作业请提交在这个目录下*/
diff --git a/Lesson-3/orgin/README.md b/Lesson-3/orgin/README.md
new file mode 100644
index 00000000..6106ea19
--- /dev/null
+++ b/Lesson-3/orgin/README.md
@@ -0,0 +1,3 @@
+## 硅谷live以太坊智能合约 第三课
+
+这里是每一课的初始代码,有需要的同学可以参考
diff --git a/Lesson-3/orgin/payroll.sol b/Lesson-3/orgin/payroll.sol
new file mode 100644
index 00000000..e69de29b
diff --git a/Lesson-4/README.md b/Lesson-4/README.md
new file mode 100644
index 00000000..34bf0bb8
--- /dev/null
+++ b/Lesson-4/README.md
@@ -0,0 +1,16 @@
+## 硅谷live以太坊智能合约频道官方地址
+
+### 第四课《使用Truffle架构进行前后端交互,测试,部署》
+
+目录结构
+
|
+
|--orgin 课程初始代码
+
|
+
|--assignment 课程作业提交代码
+
+### 本节知识点
+第4课:使用Truffle架构进行前后端交互,测试,部署
+- 为什么要用Truffle,Truffle的基本概念
+- Truffle 的command line 功能
+- 初始化项目与Truffle项目目录结构
+- 编译部署合约到testrpc
diff --git a/Lesson-4/assignment/Ownable.sol b/Lesson-4/assignment/Ownable.sol
new file mode 100644
index 00000000..54158a2a
--- /dev/null
+++ b/Lesson-4/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-4/assignment/PullPayment.sol b/Lesson-4/assignment/PullPayment.sol
new file mode 100644
index 00000000..fbd32a6f
--- /dev/null
+++ b/Lesson-4/assignment/PullPayment.sol
@@ -0,0 +1,43 @@
+pragma solidity ^0.4.18;
+
+
+import "./SafeMath.sol";
+
+
+/**
+ * @title PullPayment
+ * @dev Base contract supporting async send for pull payments. Inherit from this
+ * contract and use asyncSend instead of send.
+ */
+contract PullPayment {
+ using SafeMath for uint256;
+
+ mapping(address => uint256) public payments;
+ uint256 public totalPayments;
+
+ /**
+ * @dev withdraw accumulated balance, called by payee.
+ */
+ function withdrawPayments() public {
+ address payee = msg.sender;
+ uint256 payment = payments[payee];
+
+ require(payment != 0);
+ require(this.balance >= payment);
+
+ totalPayments = totalPayments.sub(payment);
+ payments[payee] = 0;
+
+ assert(payee.send(payment));
+ }
+
+ /**
+ * @dev Called by the payer to store the sent amount as credit to be pulled.
+ * @param dest The destination address of the funds.
+ * @param amount The amount to transfer.
+ */
+ function asyncSend(address dest, uint256 amount) internal {
+ payments[dest] = payments[dest].add(amount);
+ totalPayments = totalPayments.add(amount);
+ }
+}
diff --git a/Lesson-4/assignment/README.md b/Lesson-4/assignment/README.md
new file mode 100644
index 00000000..871e6be0
--- /dev/null
+++ b/Lesson-4/assignment/README.md
@@ -0,0 +1,12 @@
+## 硅谷live以太坊智能合约 第四课作业
+这里是同学提交作业的目录
+
+### 第四课:课后作业
+- 将第三课完成的payroll.sol程序导入truffle工程
+- 在test文件夹中,写出对如下两个函数的单元测试:
+- function addEmployee(address employeeId, uint salary) onlyOwner
+- function removeEmployee(address employeeId) onlyOwner employeeExist(employeeId)
+- 思考一下我们如何能覆盖所有的测试路径,包括函数异常的捕捉
+- (加分题,选作)
+- 写出对以下函数的基于solidity或javascript的单元测试 function getPaid() employeeExist(msg.sender)
+- Hint:思考如何对timestamp进行修改,是否需要对所测试的合约进行修改来达到测试的目的?
diff --git a/Lesson-4/assignment/SafeMath.sol b/Lesson-4/assignment/SafeMath.sol
new file mode 100644
index 00000000..788797ea
--- /dev/null
+++ b/Lesson-4/assignment/SafeMath.sol
@@ -0,0 +1,48 @@
+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-4/assignment/yours.sol b/Lesson-4/assignment/yours.sol
new file mode 100644
index 00000000..27bc3e5a
--- /dev/null
+++ b/Lesson-4/assignment/yours.sol
@@ -0,0 +1,162 @@
+pragma solidity ^0.4.18;
+
+import "./SafeMath.sol";
+import "./Ownable.sol";
+import "./PullPayment.sol";
+
+/**
+ * @title Payroll
+ * @dev Base contract supporting: adding fund, adding employees, removing
+ * employees, updating employee salary, calculating runway, checking if balance
+ * is enough, transferring contract ownership, allowing employee to get paid,
+ * allowing leave-office employee to get severance pay.
+ */
+contract Payroll is Ownable, PullPayment {
+
+ using SafeMath for uint;
+
+ uint constant PAYMENT_DURATION = 10 seconds;
+
+ struct Employee {
+ address id;
+ uint salary;
+ uint lastPaymentSettlementDate; // the last payment settlement date
+ }
+ mapping(address => Employee) employees;
+ uint public _totalSalary;
+
+ /**
+ * @dev Throws if an employee doesn't exist.
+ * @param employeeId The employee id to be checked.
+ */
+ modifier employee_exist(address employeeId) {
+ require(employees[employeeId].id != 0x0);
+ _;
+ }
+
+ /**
+ * @dev Throws if an employee exists.
+ * @param employeeId The employee id to be checked.
+ */
+ modifier employee_does_not_exist(address employeeId) {
+ require(employees[employeeId].id == 0x0);
+ _;
+ }
+
+ /**
+ * @dev Allows caller to settle the current payment of an employee.
+ * @param employeeId The id of the employee.
+ */
+ function _settlePayment(address employeeId) private {
+ Employee storage employee = employees[employeeId];
+ uint workingdays = now.sub(employee.lastPaymentSettlementDate);
+ if (workingdays > 0) {
+ asyncSend(
+ employee.id,
+ workingdays.mul(employee.salary).div(PAYMENT_DURATION)
+ );
+ employee.lastPaymentSettlementDate = now;
+ }
+ }
+
+ /**
+ * @dev Allows owner to add an employee.
+ * @param employeeId The id of the employee.
+ * @param salary The salary of the employee.
+ */
+ function addEmployee(address employeeId, uint salary)
+ public
+ onlyOwner
+ employee_does_not_exist(employeeId)
+ {
+ employees[employeeId] = Employee(employeeId, salary.mul(1 ether), now);
+ _totalSalary = _totalSalary.add(employees[employeeId].salary);
+ }
+
+ /**
+ * @dev Allows owner to remove an employee.
+ * @param employeeId The id of the employee.
+ */
+ function removeEmployee(address employeeId)
+ public
+ onlyOwner
+ employee_exist(employeeId)
+ {
+ _settlePayment(employeeId);
+ _totalSalary = _totalSalary.sub(employees[employeeId].salary);
+ delete employees[employeeId];
+ }
+
+ /**
+ * @dev Allows owner to change the salary of an employee.
+ * @param employeeId The id of the employee.
+ * @param newSalary The new salary of the employee.
+ */
+ function updateEmployeeSalary(address employeeId, uint newSalary)
+ public
+ onlyOwner
+ employee_exist(employeeId)
+ {
+ require(newSalary != employees[employeeId].salary);
+ _settlePayment(employeeId); // Settle old-rate salary payment
+ _totalSalary = _totalSalary.add(newSalary).sub(employees[employeeId].salary);
+ employees[employeeId].salary = newSalary;
+ }
+
+ /**
+ * @dev Allows an employee to transferring his payment address.
+ * @param newEmployeeId The id of the employee.
+ */
+ function changePaymentAddress(address newEmployeeId)
+ public
+ employee_exist(msg.sender)
+ {
+ require(msg.sender != newEmployeeId);
+ employees[msg.sender].id = newEmployeeId;
+ employees[newEmployeeId] = employees[msg.sender];
+ delete employees[msg.sender];
+ uint payment = payments[msg.sender];
+ delete payments[msg.sender];
+ asyncSend(newEmployeeId, payment);
+ }
+
+ /**
+ * @dev Allows adding funds/balance to the contract.
+ */
+ function addFund() public payable returns (uint) {
+ return address(this).balance;
+ }
+
+ /**
+ * @dev Allows calculating the runway of total salary.
+ */
+ function calculateRunway() public returns (uint) {
+ return address(this).balance.div(_totalSalary);
+ }
+
+ /**
+ * @dev Allows checking if the contract has enough fund.
+ */
+ function hasEnoughFund() public returns (bool) {
+ return (calculateRunway() > 0);
+ }
+
+ /**
+ * @dev Allows employee to get paid.
+ */
+ function getPaid() public employee_exist(msg.sender) {
+ _settlePayment(msg.sender);
+ withdrawPayments();
+ }
+
+ /**
+ * @dev Allows left-office employee to get severance pay.
+ */
+ function getSeverancePay()
+ public
+ employee_does_not_exist(msg.sender)
+ {
+ require(payments[msg.sender] > 0);
+ withdrawPayments();
+ }
+}
diff --git a/Lesson-4/orgin/README.md b/Lesson-4/orgin/README.md
new file mode 100644
index 00000000..c27ba052
--- /dev/null
+++ b/Lesson-4/orgin/README.md
@@ -0,0 +1,3 @@
+## 硅谷live以太坊智能合约 第四课
+
+这里是每一课的初始代码,有需要的同学可以参考
diff --git a/Lesson-4/orgin/payroll.sol b/Lesson-4/orgin/payroll.sol
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/Lesson-4/orgin/payroll.sol
@@ -0,0 +1 @@
+