@(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); } }
參考閱讀:老董-以太坊智能合約全棧開發