本文已参与「新人创作礼」活动,一起开启掘金创作之路。
加油,卷起来!
取消防溢出
unchecked{ //不防溢出
++i;
}
Merkle Tree
从上到下一直算哈希值,直到顶上,这代表默克尔树一定是一个完全二叉树
uniswap大概原理
类似uniswap这种,都不是把代币放到自己的池子里,而是把代币通过token的形式先赋予授权给合约地址,然后在直接在两个token的合约中进行交换
通过字节码的方式部署合约
插槽数值写入:
payable address
payable address类型,你如果想要向这个地址付款,必须使用payable adress的变量!=payable address变量!
问题:
转账: msg.sender.call{value: amount}("") 为什么是这样的?
接口实现
interface:声明这个合约有实现的功能,但是你勿需在当前合约的文件中实现
两种不同形式的交易
english auction:every bid the price higher and higher
dutch auction:the auction holder start with a really high price,with time goes by ,the auction hodler lower the price.the one who shout out the price get win the autcion
delegatecall:
重要点:
You must keep 2 things in mind when using delegatecall
- delegatecall preserves context (storage, caller, etc...)这个保留上下文,就像是把代码放到这段代码中运行一样
- storage layout must be the same for the contract calling delegatecall and the contract getting called,两个地方的存储布局必须相同
随机数生成
攻击者简单复制了代码就得到了相同的数据
不要使用 blockhash 和 block.timestamp 作为随机源!
msg.sender和tx.orign
What's the difference between msg.sender and tx.origin?这二者的差别
If contract A calls B, and B calls C, in C msg.sender is B and tx.origin is A.
调用外部合约:
bar = new Bar();
//在本地生成一个新的bar,而不是去找,防止由地址掉包导致的混淆(根本就不要地址了)
bar=Bar(_bar_address);//去找那个位置的bar
### revert
revert
revert('it's a trap')-->可以把整个交易给破坏掉,回到没有发生过的状态
// Let's say this code is in a separate file so that others cannot read it.
!isContract(msg.sender):如果发送者不是合约
contract Target {
function isContract(address account) public view returns (bool)
{ // This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution. uint size;
assembly { size := extcodesize(account) }
return size > 0; }
but:
// When contract is being created, code size (extcodesize) is 0.
// This will bypass the isContract() check