zoukankan      html  css  js  c++  java
  • 135.002 智能合约设计-——多员工薪酬系统

    @(135- Block Chain| 区块链)

    Introduciton

    可调整地址和薪水的单员工系统

    • address neo -> address employee
    • funtion updateEmployee

    Goal——多员工系统
    Solution—— 数组+结构体

    • Employee[] employees
    • funtion addEmployee
    • funtion removeEmployee

    1 错误检测

    代码风格——方便简洁

    • assert(bool) //程序运行时——确认

    • require(bool)//程序输入时——要求

        require(msg.sender == owner);
        // if(msg.sender != employee){//了解调用者信息
        //     revert();
        // }
        assert(nextPayday < now);
        // if( nextPayday > now){
        //     revert();
      

    2 Data Location | Solidity数据存储

    • storage
      永久存储在区块链上
    • memory

    临时空间,在function结束后释放

    • calldata
      与memory类似

    2.1强制类型

    状态变量:storage
    function 输入变量:calldata

    2.2 默认类型

    function 返回类型:memory
    本地变量:storage

    2.3 变量本质

    类比c++的地址
    指向 EVM中的一块内存区域

    2.4 规则

    • 相同的存储空间变量赋值
      • 传递reference(EVM上的内存地址)
    • 不同存储空间变量赋值
      • 拷贝

    3 Code in Remix (Solidity IDE)

    pragma solidity ^0.4.0;
    
    contract Payroll{
        
        
        struct Employee{
            address id;
            uint salary;
            uint lastPayday;
        }
        
        
      // uint constant payDuration = 30 days;
       uint constant payDuration = 10 seconds;//for test:10 seconds
       
       address owner;
       Employee[] employees;//dynamic array 
         function Payroll(){//construction function
        
        owner = msg.sender;
            
        }
        function _partialPaid(Employee employee) private{
                uint payment = employee.salary * (now - employee.lastPayday) /payDuration;//if exist , calculate payment注意整除
                employee.id.transfer(payment);
        }
        
        function _findEmloyee(address employeeId) private returns (Employee,uint){//Encapsulation 封装 
            for (uint i=0;i<employees.length;i++)//avoid needless duplication (repeat)
            {
                if (employees[i].id == employeeId){
                    return (employees[i],i);
                } 
            }
        
        }
        function addEmployee(address employeeId,uint salary){
            require(msg.sender == owner);//whether is onwner
    
            var (employee,index ) = _findEmloyee(employeeId); //var - any type
            assert(employee.id == 0x0);//confirm that exist
            
            employees.push(Employee(employeeId,salary,now));
        }
        
        function removeEmployee(address employeeId){
             require(msg.sender == owner);//whether is onwner
             var (employee,index) = _findEmloyee(employeeId); 
             assert(employee.id != 0x0);//confirm that exist
            _partialPaid(employees[index]);
            delete employees[index];//left with a blank in the array,wasteful
            employees[index] = employees[employees.length - 1];//fill the blank
            employees.length -= 1;
          
    
        
    }
        
        function updateEmployee(address employeeId,uint salary) {
            require(msg.sender == owner);
            //Equivalently 等效 
            // if (msg.sender != owner){//avoid employee cheating
            //     revert();
            // }
            
             var (employee,index) = _findEmloyee(employeeId); 
             assert(employee.id != 0x0);//confirm that exist
            _partialPaid(employee);
            employees[index].salary = salary;
            employees[index].lastPayday = now;     
             
    
        }
        
        function addFund() payable returns(uint){
            return this.balance;//address.balance
        }
        
        
        function calculateRunway()returns(uint)
        { //how many times to pay
            uint totalSalary = 0;
            for (uint i=0;i<employees.length;i++)
             {
                 totalSalary += employees[i].salary; 
             } 
    
            return this.balance / totalSalary; 
        }
        function hasEnoughFund() returns(bool){
            // return this.balance >=salary;
            //return this.calculateRunway() > 0; //this方法 使用的gas 较多,不推荐
            return calculateRunway() > 0; //vm jump 操作,使用gas较少,推荐
        }
        function getPaid (){
             var (employee,index) = _findEmloyee(msg.sender); 
             assert(employee.id != 0x0);//confirm that exist
            uint nextPayday = employee.lastPayday + payDuration;
             //每一次运算都是真金白银~
             //原则:不重复运算!——省gas
            assert(nextPayday < now);
            // if( nextPayday > now){
            //     revert();
                  //throw or revert
                //throw: 所有的gas 均会被消耗殆尽
                //revert:回滚,return没有消耗的gas
               
            // }
            
                employees[index].lastPayday = nextPayday;//原则:先修改内部变量,再给钱——》之后会讲,安全问题
                employee.id.transfer(employee.salary);
    
        }
    }
    

    参考阅读:老董-以太坊智能合约全栈开发

  • 相关阅读:
    java和.NET的比较
    联想笔记本不能无线上网
    js根据给定的日期计算当月有多少天
    jQuery中live()变更
    C#操作xml文件
    SQL server的with的用法(一)
    jquery拖拽实现UI设计组件
    自定义弹出框
    第一个超级简单Node.js实例
    windows 下使用redis
  • 原文地址:https://www.cnblogs.com/Neo007/p/9248580.html
Copyright © 2011-2022 走看看