@(135- Block Chain| 区块链)python
如何减小gas 消耗?
(本质为节约计算资源,下降时间复杂度的问题)
数组越大,遍历所需资源越多
遍历数组 traverse array——> 映射 Mappingc++
类比map(c++),dict(python)
Hash table
Key - Valuegit
types of Key in solidity
(bool,int ,address,string)程序员
mapping只能做为合约的成员变量,而不能作本地局部变量github
当key 不存在,value = type's default // 不会抛出异常数组
1.命名参数返回安全
function checkEmployee(address employeeId) returns(uint salary,uint lastPayday){ //quary the information of employees //name the returned parameter 命名参数返回
OUTPUT
{
"0": "uint256: salary 1000000000000000000",
"1": "uint256: lastPayday 1530411588"
}数据结构
2.命名返回参数直接赋值app
等效代码框架
// return (employee.salary,employee.lastPayday); salary = employee.salary; lastPayday = employee.lastPayday;
合约的全部成员变量都是肉眼可见的!!!
private 对继承类不可见
contract Parent{ function someFunc() returns (uint); } contract Child is Parent{ function someFunc() returns (uint){ return 1; } }
pragma solidity ^0.4.0; interface Parent{ //不可继承其余合约或Interface //没有构造函数 //没有状态变量 //没有struct //没有enum //简单来讲,只有function定义,啥都没有 function someFunc() returns (uint); } contract Child is Parent{ function someFunc() returns (uint){ return 1; } }
contract Base1{ function func1(){} } contract Base2{ function func1(){} } contract Final is Base1,Base2 { } contract test{ Final f = new Final(); f.func1();//Base2 的function1被调用(从后往前,因为先继承base1,再继承base2) }
contract foundation{ function func1{ //do stuff } } contract Base1 is foundation{ function func1(){ super.func1(); } } contract Base2 is foundation{ function func1(){ super.func1(); } } contract Final is Base1,Base2{ Final f = new Final(); f.func1(); } //调用顺序:Base2.func1,Base1.func1,foundation.func1
pragma solidity ^0.4.0 contract Parent { uint public a=2; modifier someModifier(){ _; a = 1; } function parentFunc2(uint value) someModifer public returns(uint){ a = value; //下划线等效加入一句 modify a=1; return a; } }
contract Test { uint8 public a = 0; function set(){ a -= 100; } } OUTPUT:整型溢出 a: uint8: 156
手动解决方法_silly
contract Test { uint8 public a = 0; function set(){ uint c = a - 100; assert(c<a); a = c; } }
solidity ^0.4.0; import './SafeMath.sol'; //local file,download from github contract Test { using SafeMath for uint8; uint8 public a = 0; function set(){ a = a.sub(100); //a = SafeMath.sub(a,100); } }
pragma solidity ^0.4.14; import './SafeMath.sol'; import './Ownable.sol'; //Github - Zppelin-solidity contract Payroll{ using SafeMath for uint; struct Employee{ address id; uint salary; uint lastPayday; } // uint constant payDuration = 30 days; uint constant payDuration = 10 seconds;//for test:10 seconds uint totalSalary; address owner; mapping(address => Employee)public employees; // function Payroll(){//construction function // owner = msg.sender; // in ownable.sol // } // modifier onlyOwner{ //in Ownable.sol // require(msg.sender == owner); // _; //represent the function been modified, 除了return以外的语句 // } modifier employeeExist(address employeeId){ var employee = employees[employeeId]; assert(employee.id != 0x0);//confirm that exist _; } function _partialPaid(Employee employee) private{ uint payment = employee.salary * (now - employee.lastPayday) /payDuration;//if exist , calculate payment注意整除 employee.id.transfer(payment); } function addEmployee(address employeeId,uint salary)onlyOwner{ // require(msg.sender == owner);//whether is onwner var employee = employees[employeeId];//var - any type assert(employee.id == 0x0);//confirm that exist totalSalary += salary *1 ether; employees[employeeId] = Employee(employeeId,salary* 1 ether,now); } function removeEmployee(address employeeId)onlyOwner employeeExist(employeeId){ // require(msg.sender == owner);//whether is onwner // var (employee,index) = _findEmloyee(employeeId); var employee = employees[employeeId]; _partialPaid(employee); totalSalary -=employees[employeeId].salary; delete employees[employeeId];//left with a blank in the array,wasteful } function updateEmployee(address employeeId,uint salary)onlyOwner employeeExist(employeeId){ //require(msg.sender == owner); //Equivalently 等效 // if (msg.sender != owner){//avoid employee cheating // revert(); // } var employee = employees[employeeId]; _partialPaid(employee); totalSalary -= employees[employeeId].salary; employees[employeeId].salary = salary *1 ether; totalSalary += employees[employeeId].salary; employees[employeeId].lastPayday = now; } function addFund() payable returns(uint){ return this.balance;//address.balance } function calculateRunway()returns(uint) { //how many times left to pay 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 checkEmployee(address employeeId) returns(uint salary,uint lastPayday){ //quary the information of employees //name the returned parameter 命名参数返回 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]; //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[msg.sender].lastPayday = nextPayday;//原则:先修改内部变量,再给钱——》以后会讲,安全问题 employee.id.transfer(employee.salary); } }
参考阅读:老董-以太坊智能合约全栈开发