27. ABI编码解码
WTF Solidity极简入门: 27. ABI编码解码
我最近在重新学 Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新 1-3 讲。
推特:@0xAA_Science|@WTFAcademy_
社区:Discord|微信群|官网 wtf.academy
所有代码和教程开源在 github: github.com/AmazingAng/WTF-Solidity
ABI (Application Binary Interface,应用二进制接口)是与以太坊智能合约交互的标准。数据基于他们的类型编码;并且由于编码后不包含类型信息,解码时需要注明它们的类型。
Solidity中,ABI编码有4个函数:abi.encode, abi.encodePacked, abi.encodeWithSignature, abi.encodeWithSelector。而ABI解码有1个函数:abi.decode,用于解码abi.encode的数据。这一讲,我们将学习如何使用这些函数。
ABI编码
我们将编码4个变量,他们的类 ...
26. 删除合约
WTF Solidity极简入门: 26. 删除合约
我最近在重新学 Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新 1-3 讲。
推特:@0xAA_Science|@WTFAcademy_
社区:Discord|微信群|官网 wtf.academy
所有代码和教程开源在 github: github.com/AmazingAng/WTF-Solidity
selfdestruct
selfdestruct命令可以用来删除智能合约,并将该合约剩余ETH转到指定地址。selfdestruct是为了应对合约出错的极端情况而设计的。它最早被命名为suicide(自杀),但是这个词太敏感。为了保护抑郁的程序员,改名为selfdestruct;在 v0.8.18 版本中,selfdestruct 关键字被标记为「不再建议使用」,在一些情况下它会导致预期之外的合约语义,但由于目前还没有代替方案,目前只是对开发者做了编译阶段的警告,相关内容可以查看 EIP-6049。
然而,在以太坊坎昆(Cancun)升级中,EIP-6 ...
25. Create2
WTF Solidity极简入门: 25. CREATE2
我最近在重新学 Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新 1-3 讲。
推特:@0xAA_Science|@WTFAcademy_
社区:Discord|微信群|官网 wtf.academy
所有代码和教程开源在 github: github.com/AmazingAng/WTF-Solidity
CREATE2
CREATE2 操作码使我们在智能合约部署在以太坊网络之前就能预测合约的地址。Uniswap创建Pair合约用的就是CREATE2而不是CREATE。这一讲,我将介绍CREATE2的用法
CREATE如何计算地址
智能合约可以由其他合约和普通账户利用CREATE操作码创建。 在这两种情况下,新合约的地址都以相同的方式计算:创建者的地址(通常为部署的钱包地址或者合约地址)和nonce(该地址发送交易的总数,对于合约账户是创建的合约总数,每创建一个合约nonce+1)的哈希。
1新地址 = hash(创建者地址, nonce)
创建者地 ...
24. 在合约中创建新合约
WTF Solidity极简入门: 24. 在合约中创建新合约
我最近在重新学 Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新 1-3 讲。
推特:@0xAA_Science|@WTFAcademy_
社区:Discord|微信群|官网 wtf.academy
所有代码和教程开源在 github: github.com/AmazingAng/WTF-Solidity
在以太坊链上,用户(外部账户,EOA)可以创建智能合约,智能合约同样也可以创建新的智能合约。去中心化交易所uniswap就是利用工厂合约(PairFactory)创建了无数个币对合约(Pair)。这一讲,我会用简化版的uniswap讲如何通过合约创建合约。
create
有两种方法可以在合约中创建新合约,create和create2,这里我们讲create,下一讲会介绍create2。
create的用法很简单,就是new一个合约,并传入新合约构造函数所需的参数:
1Contract x = new Contract{value: _ ...
无题
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("create2 test", function () {
it("Should return the new create2test once it's changed", async function () {
console.log("1.==> deploy pair");
const PairFactory = await ethers.getContractFactory("Pair");
const Pair = await PairFactory.deploy();
await Pair.waitForDeployment();
console.log("pair address =>",Pair.target);
console.log();
console.log("2.==> deploy PairFactory2");
...
23. Delegatecall
WTF Solidity极简入门: 23. Delegatecall
我最近在重新学 Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新 1-3 讲。
推特:@0xAA_Science|@WTFAcademy_
社区:Discord|微信群|官网 wtf.academy
所有代码和教程开源在 github: github.com/AmazingAng/WTF-Solidity
Delegatecall
delegatecall与call类似,是Solidity中地址类型的低级成员函数。delegate中是委托/代表的意思,那么delegatecall委托了什么?
当用户A通过合约B来call合约C的时候,执行的是合约C的函数,上下文(Context,可以理解为包含变量和状态的环境)也是合约C的:msg.sender是B的地址,并且如果函数改变一些状态变量,产生的效果会作用于合约C的变量上。
而当用户A通过合约B来delegatecall合约C的时候,执行的是合约C的函数,但是上下文仍是合约B的:msg.sen ...
22. Call
WTF Solidity极简入门: 22. Call
我最近在重新学 Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新 1-3 讲。
推特:@0xAA_Science|@WTFAcademy_
社区:Discord|微信群|官网 wtf.academy
所有代码和教程开源在 github: github.com/AmazingAng/WTF-Solidity
我们曾在第20讲:发送ETH那一讲介绍过利用call来发送ETH,这一讲我们将介绍如何利用它调用合约。
Call
call 是address类型的低级成员函数,它用来与其他合约交互。它的返回值为(bool, bytes memory),分别对应call是否成功以及目标函数的返回值。
call是Solidity官方推荐的通过触发fallback或receive函数发送ETH的方法。
不推荐用call来调用另一个合约,因为当你调用不安全合约的函数时,你就把主动权交给了它。推荐的方法仍是声明合约变量后调用函数,见第21讲:调用其他合约
当我们不知道对方合约的 ...
21. 调用其他合约
WTF Solidity极简入门: 21. 调用其他合约
我最近在重新学 Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新 1-3 讲。
推特:@0xAA_Science|@WTFAcademy_
社区:Discord|微信群|官网 wtf.academy
所有代码和教程开源在 github: github.com/AmazingAng/WTF-Solidity
调用已部署合约
在Solidity中,一个合约可以调用另一个合约的函数,这在构建复杂的DApps时非常有用。本教程将会介绍如何在已知合约代码(或接口)和地址的情况下,调用已部署的合约。
目标合约
我们先写一个简单的合约OtherContract,用于被其他合约调用。
123456789101112131415161718192021222324contract OtherContract { uint256 private _x = 0; // 状态变量_x // 收到eth的事件,记录amount和gas event L ...
20. 发送ETH
WTF Solidity极简入门: 20. 发送ETH
我最近在重新学 Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新 1-3 讲。
推特:@0xAA_Science|@WTFAcademy_
社区:Discord|微信群|官网 wtf.academy
所有代码和教程开源在 github: github.com/AmazingAng/WTF-Solidity
Solidity有三种方法向其他合约发送ETH,他们是:transfer(),send()和call(),其中call()是被鼓励的用法。
接收ETH合约
我们先部署一个接收ETH合约ReceiveETH。ReceiveETH合约里有一个事件Log,记录收到的ETH数量和gas剩余。还有两个函数,一个是receive()函数,收到ETH被触发,并发送Log事件;另一个是查询合约ETH余额的getBalance()函数。
1234567891011121314contract ReceiveETH { // 收到eth事件,记录amoun ...
19. 接收ETH
WTF Solidity极简入门: 19. 接收ETH receive和fallback
我最近在重新学 Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新 1-3 讲。
推特:@0xAA_Science|@WTFAcademy_
社区:Discord|微信群|官网 wtf.academy
所有代码和教程开源在 github: github.com/AmazingAng/WTF-Solidity
Solidity支持两种特殊的回调函数,receive()和fallback(),他们主要在两种情况下被使用:
接收ETH
处理合约中不存在的函数调用(代理合约proxy contract)
注意⚠️:在Solidity 0.6.x版本之前,语法上只有 fallback() 函数,用来接收用户发送的ETH时调用以及在被调用函数签名没有匹配到时,来调用。
0.6版本之后,Solidity才将 fallback() 函数拆分成 receive() 和 fallback() 两个函数。
我们这一讲主要讲接收ETH的情况。 ...