本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1.小猪存钱罐
指的是这个合约可以存钱,会被打碎(只能存一次钱)
取钱由于只要取一次:可以直接用seldestruct(payable(msg.sender))即可
2.erc20
erc20合约只是指接口,有了接口就算满足,没有一个唯一的代码
interface 如果被继承了,那么其中的所有方法都需要实现
transfer和transferFrom有什么区别?
1)假设我有100个shib,我想转给你,我就用transfer进行转移;
2)假设我有100个shib但是你没有,我给你做了一个allowance,你就用transferfrom给我。
3.多签钱包
所有所有者:address[],但是如何快速判断所有的值中是否有某一地址?
通过做一个mapping,如果有就赋值为true,减少单词检索的gas
4.函数签名:
函数签名
1:获取函数选择器+类型做哈希,拿到前四个字节(4bytes)(8位);输入uint类型的时候要输入uint256
2.后面加上参数
说明了一个问题:多态在这里是支持的,只要你的类型不一样就可以;参数不同,名字相同即可。
5.荷兰拍
为了让荷兰拍卖的代码能工作:即能转移nft,需要在合约里对这个nft进行approve,做过这个之后,才能成功地让拍卖合约完成交易后转移nft
6.英式拍卖
主要有一下几个功能:
1.出价---->不断地出价,后面出地价格加到那个人地身上
2.取回----->通过取回函数取回钱
3.拍卖结束合约----->付诸交易的实现
7.众筹合约
时间戳--->uint32存储就够了
###8.create2:可以在合约部署之前就知道未来将要部署的位置
原来合约部署是和nonce和编码有关;
现在使用create2会受salt的变化和编码的变化而变化,salt是bytes32
function getAddress(bytes memory bytecode, uint _salt)
public view returns (address) {
bytes32 hash = keccak256(
abi.encodePacked(bytes1(0xff),
address(this), _salt,
keccak256(bytecode))
);
// NOTE: cast last 20 bytes of hash to address return address(uint160(uint(hash))); }
9.多重调用:multicall
1.在数组中传递值的时候,应当使用[“”]把元素扩起来
2.call不能写在view的函数里,staticcall可以,因为其更加静态,不能改变被呼叫的合约的状态
10.多重委托调用只能调用自己:继承后才可以
但是要防止多重接收主币!!!!
这样会重复,相当于多重调用了三次传来1ether,最后会显示为3个ether
11.abi编解码(这里还需要继续收集一下!)
编码: abi.encode(x,addr,arr,mystruct);
解码:abi.decode(data,(uint,address,uint[],Mystruct))
如果你想要把结构体输入到remix的输入框中,直接就像输入一个多维数组一样输入就可以;但是解码后输入的字符串在remix上面是无法显示的。
12.GAS优化
1,优先使用calldata
2,加载状态变量到内存变量,省得一次次去读
3,多个条件判断使用短路方式:判断条件之前不要先赋值,应该直接放到if中
4,在循环中使用++i,而不是i+=1,i++(离谱)
5,数组长度缓存到内存:
```
uint len=nums.length;
for(****;i<len;++i)
```
6,缓存多次使用的数组元素到内存
13.时间锁合约,
一些重要的合约修改必须等一段时间,用作队列/数组完成时间操作