# 智能合约开发-1 **Published by:** [vim](https://paragraph.com/@vimyang-2/) **Published on:** 2022-04-03 **URL:** https://paragraph.com/@vimyang-2/1 ## Content lesson-1-hello几个知识点msg是内部变量,不能使用函数的参数变量,不需要存储,因此可以指定类型之后,添加```memory```关键词如果函数返回内部变量,只读,可以使用关键词```view```返回变量的关键词是```returns```,而不是```return```// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.4; contract Hello { string public name; function setName(string memory name_) public{ name = name_; } function getName() public view returns (string memory){ return name; } } 使用msg的时候,出现如下的编译警告Warning: This declaration shadows a builtin symbol. --> contracts/lesson/lesson-1-hello.sol:7:5: | 7 | string public msg; | ^^^^^^^^^^^^^^^^^ lesson-2-unitEth以太坊中单位的对应关系// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.4; contract EthUint { uint public oneWei = 1 wei; uint public oneGwei = 1 gwei; uint public oneEth = 1 ether; function testOneWei() public view returns (bool) { return oneWei == 1; } function testOneGgei() public view returns (bool) { return oneGwei == 1 * 10**9; } function testOneEth() public view returns (bool) { return oneEth == 1 * 10**18; } } 也可以参考网站:https://eth-converter.com/lesson-3-fun-visibility函数的可见性严格排序// private internal external public // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.4; // private internal external public contract funVisibility { uint age; function funPublic() public view returns (uint){ return age; } function funExternal() external view returns (uint){ return age; } function funInternal() internal view returns (uint){ return age; } function funPrivate() private view returns (uint){ return age; } function testFun() public view returns(uint) { // return funPublic(); // ok // return funExternal(); // not ok // return funInternal(); // ok return funPrivate(); // ok } } contract subFunVisibility is funVisibility{ function testParentFun() public view returns(uint) { // return funPublic(); // ok // return funExternal(); // not ok // return funInternal(); // ok // return funPrivate(); // not ok } } 扩展阅读:https://tsaiyee.com/blog/2018/01/07/solidity-external-public-best-practices/ 【Solidity中的external与public使用最佳实践】lesson-4-inherit 继承知识点继承的语法是子类 is 父类如果需要重写父类函数,父类定义需要使用virtual,子类需要使用pure override如果父类构造函数有参数,子类定义的时候,也需要为父类指定构造函数的参数// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.4; // private internal external public contract Parent { uint age; constructor(uint age_){ age = age_; } function getAge() public view returns (uint){ return age; } function getDesc() public view virtual returns (string memory){ return "Parent"; } } contract Son is Parent(55){ // can call getAage fun function getDesc() public pure override(Parent) returns (string memory){ return "Son"; } } 扩展阅读:https://medium.com/taipei-ethereum-meetup/solidity-weekly-11-70c5208a3bf1 【pure 跟 view 的区别】 更正確的講,如果一個 function 不會改變到合約的 state,就可以加 modifier constant 在 returns 前面,因此在 web3.js 就可以用 call() 來呼叫該 function, 而不需要用 sendTransaction() 來呼叫。 到了 solc 0.4.17, 更把 constant 細分為 view 或 pure 兩種,只是程度上的不同。 view 一般來說,就用來取代 constant, 跟 compiler 説,該 function 不會對 storage state 有任何變動。(但會進行讀取, 所以 constant 改名為 view,更為恰當)string greeting; function SayHello() public view returns(string says) { return greeting; } pure 定義該 function 連讀 storage state 都沒有。有人舉了一個誇張的例子如下:(它跟合約的所有 states 都無關, 可以加 modifier pure)function returnTrue() public pure returns(bool response) { return true; } lesson-5-multiInherit // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.4; // private internal external public contract A { uint age; constructor(uint age_){ age = age_; } function getAge() public view returns (uint){ return age; } } contract B { string name; constructor(string memory name_){ name = name_; } function getNmae() public view returns (string memory){ return name; } } contract C is A, B{ constructor()A(10) B ("hello"){ } } contract D is A, B{ constructor(uint age_, string memory name)A(age_) B (name){ } } lesson-6-event// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.4; contract Event { event Log(address sender, string msg ); function trancfer() public{ emit Log(msg.sender, "This is 1 mag"); emit Log(msg.sender, "This is 2 mag"); emit Log(msg.sender, "This is 3 mag"); } } lesson-7-globalVal // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.4; contract Hello { event Log(address, uint); function getGasInfo() public view returns(uint, uint){ return (tx.gasprice, block.gaslimit); } function getMagInfo () public payable { emit Log(msg.sender, msg.value); } } lesson-8-errorHandle 参数尽量提前检查,多执行代码,会增加gas费// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.4; contract ErrorHandle { int public balance = 0; function add(int trans_num) public{ require(trans_num >= 0, "The trans num should big than 0"); // int old_balance = balance; balance += trans_num; //assert(balance >= old_balance); // if(balance < old_balance){ // revert("error"); // } } } lesson-9-array需要注意的是,array的del函数并没有删除数据,只是把数据进行了清空// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.4; // array // push pop del length contract Array { uint[] public array1; uint[3] public array2; uint [] public arrar3 = [1,2,3]; function push(uint val) public{ array1.push(val); } function pop() public{ array1.pop(); } function length() public view returns(uint){ return array1.length; } function del(uint index) public{ // param check delete array1[index]; } function test() public{ array1.push(1); array1.push(2); array1.push(3); array1.push(4); assert(length() == 4); pop(); assert(length() == 3); assert(array1[2] == 3); del(2); assert(length() == 3); assert(array1[2] == 0); } } lesson-10-map需要注意的是map的del函数,也只是把数据清空而不会把数据真正的删除map没有遍历函数,如果希望遍历,可以添加一个辅助的数组// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.4; contract Map { mapping(address => uint) public MyMap; function setMap(address add_, uint num) public{ MyMap[add_] = num; } function delMap(address addr_) public{ delete MyMap[addr_]; } function getlMap(address addr_) public view returns (uint){ return MyMap[addr_]; } } lesson-11-struct注意事项外部string参数使用memory修饰,int、bool等类型无需内部结构体需要使用storage修饰// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.4; contract Struct { struct Todo{ string task; bool complete; } Todo [] public todo_list; function add(string memory _task) public { // Todo memory todo = Todo(_task, false); // Todo memory todo = Todo({ // task: _task, // complete : false // }); Todo memory todo; todo.task = _task; todo.complete = false; todo_list.push(todo); } function get(uint index) public view returns (Todo memory){ return todo_list[index]; } function getEle(uint index) public view returns (string memory, bool){ Todo storage todo = todo_list[index]; return (todo.task, todo.complete); } } ## Publication Information - [vim](https://paragraph.com/@vimyang-2/): Publication homepage - [All Posts](https://paragraph.com/@vimyang-2/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@vimyang-2): Subscribe to updates - [Twitter](https://twitter.com/vim12128250): Follow on Twitter