目录

Web3系列教程之入门篇---7. 一些需要注意的学习点

有一些话题不太值得单独拿出一个章节去说,但是确有助于我们理解和学习。其中一些关键点会都放到这里来说明。

目录:

  • 提供者和签名者
  • BigNumbers
  • ABI
  • React Hooks
  • ERC20 Approval 流程

提供者和签署者

在构建智能契约的接口时,您通常会遇到这两个术语—— ProviderSigner。当你真正开始使用它们的时候,你会对它们有一个更好的理解,我们会试着提供一个简短的解释。

我们知道要向区块链读取或写入数据,我们需要通过以太节点进行通信。节点包含区块链状态,允许我们读取数据。它还可以向矿工广播事务,允许我们写数据。

注意,节点只需要广播事务,以防您想要将数据写入区块链。因为如果你只是阅读已经存在的数据,矿工不需要做任何事情,他们已经完成了他们的工作。

Provider是一个以太节点连接,允许您从其状态读取数据。您将使用 Provider 来执行诸如在智能契约中调用只读函数、获取帐户余额、获取事务详细信息等操作。

Signer 是一个以太节点连接,允许您将数据写入区块链。您将使用 Signer 执行诸如在智能合同中调用 write 函数、在帐户之间传输 ETH 等操作。为此,签名者需要访问一个私钥,它可以使用这个私钥代表一个帐户进行交易。

此外,Signer 可以完成提供程序可以完成的所有工作。您可以同时使用 Signer 进行读取和写入,但是 Provider 只适合于读取数据。

默认情况下,像 Metamask 这样的钱包会在你的浏览器中注入一个提供者。因此,dApps 可以使用 Metamask Provider 从钱包连接的区块链网络读取值。

但是,有时您希望用户进行事务处理,而不仅仅是读取数据。当然,Metamask 不能与随机网站到处分享你的私人密钥-这将是疯狂的。为此,Metamask 还允许网站请求一个 Signer。因此,当 dApp 试图向块链发送事务时,Metamask 窗口会弹出,要求用户确认该操作。

BigNumbers

在学习 Solidy 的时候,我们已经阅读和使用了大量的 uint256Uint256的范围从0到(2 ^ 256)-1。因此,uint256数据类型可以容纳的最大数量是天文数字。

具体来说,uint256的最大值是:

1
115792089237316195423570985008687907853269984665640564039457584007913129639935

相比之下,100万是:

1
1000000

显然,uint256可以容纳非常大的数字,但是这带来了一个问题。

我们通常在 Javascript 中为智能合约构建接口。

具体来说,Javascript 可以容纳的数值类型的最大值是:

1
9007199254740991

这和 uint256的容量还差得远呢!

因此,假设我们使用 Javascript 对返回 uint256的智能契约调用一个函数。如果这个数字大于 Javascript 的最大值,这是完全有可能的,那么会发生什么?

事实证明,Javascript 不能支持这个。因此,我们必须使用一种称为 BigNumber 的特殊类型。用于与 Etherum 节点交互的库-ethers.jsweb3.js-都支持 BigNumbers。

BigNumber 是一个用 Javascript 编写的自定义类库,它为数学函数(add、 sub、 mul、 div 等)引入了自己的函数。BigNumber 对数字的容量比 Javascript 本地支持的要大得多。

当我们在以下级别编写代码时,您将遇到通过调用。add()mul()而不是我们知道的典型的 +* 运算符-这是因为当我们使用BigNumbers时,我们需要使用它的数学函数。

至于会发生什么,如果我们试图这样做与 Javascript 编号,我们会很容易溢出或下溢。这意味着我们的计算将是完全不正确和未定义的。所以,记住这一点。

ABI

ABI 代表应用二进制接口。在使用以太坊时,这是一个比较棘手的问题,但我们会尽力解释清楚。

在新手教程中,以及在教程中您将进一步遇到的,您将大量使用 ABI。

在编译 Solidy 代码时,它被编译成基本上是二进制的字节码。它不包含契约中存在的函数名、它们包含的参数以及它们返回的值的记录。

然而,如果你想从 web 应用程序中调用 Solidy 函数,你需要一种方法来调用合同中正确的字节码。为此,您需要一种方法来将人类可读的函数名和参数转换为字节码并返回。

ABI 帮助我们实现了这一点。当您编译 Solidy 代码时,编译器会自动生成 ABI。它包含关于契约中函数的规则和元数据,这些规则和元数据有助于来回进行正确的数据转换。

因此,当您想要调用一个契约时,您需要它的地址(当然) ,但是您也需要提供它的 ABI。像 ethers.js 这样的库使用 ABI 将人类可读的函数编码和解码成字节码,然后在与 Etherum 节点通信以及在智能契约中调用函数时返回。

ERC20 Approval 流程

在过去,我们学习了payable函数,当一个函数被调用允许智能合同接受 ETH 支付。如果您想用 ETH 向用户收取费用以换取某些东西,例如 NFT 销售,那么这非常有用。

但是,如果您想使用 ETH 以外的东西来支付呢?如果您想使用自己用于支付的加密货币,该怎么办?

事情有点棘手。

由于以太坊是 Ethereum 的本土货币,而 ERC20标准是在以太坊发明之后很久才引入的,因此它们的表现并不完全相同。具体来说,接受 ERC20令牌中的支付并不仅仅是使函数在 Solidy 中payable 那么简单。

payable 关键字只适用于 ETH 支付。如果您希望使用自己的 ERC20加密货币,那么执行该操作的流程要稍微复杂一些。

首先,让我们考虑一下这个问题。

  • 好的,所以你不能像使用ETH那样,在调用函数的同时发送ERC20代币
  • 也许智能合约可以以某种方式从函数调用者的账户中提取代币?
  • 但这意味着我可以编写一个智能合约,如果有人用我的合约进行交易,就会窃取所有人的代币。
  • 因此,我们需要一种更安全的方式来从某人的账户中提取代币

这就是 "Approve and Transfer "流程的作用。

ERC20标准带有Allowance的概念。

https://hicoldcat.oss-cn-hangzhou.aliyuncs.com/img/20220710133841.png

让我们试着借助一个例子来思考这个问题。

  • Alice 想出售她的NFT
  • Alice希望以她自己的加密货币AliceCoin来接受她的NFT的支付。
  • Alice的NFT花费10个AliceCoin
  • Bob拥有AliceCoin
  • Bob想购买Alice的NFT
  • Bob需要一种方法来调用Alice的NFT智能合约上的一个函数,这个函数将接受10个AliceCoin的付款,并向他发送他的NFT
  • 由于智能合约不能直接接受Alicecoin作为支付手段,Alice在她的NFT合约中编码了ERC20 Approval and Transfer

Alicecoin是一种ERC20代币。ERC20内置了一些与Allowance概念相关的功能。

approve(address spender, uint256 amount)

这允许用户approve 一个不同的地址代表他们消费amount 的代币,即该功能向spender提供amount的津贴。

transferFrom(address from, address to, uint256 amount)

允许用户将amount 数量的token从一个地方转移到另一个地方。

如果调用该函数的用户与from地址相同,代币将从用户的余额中移除。

如果用户是来自from 以外的人,from 地址必须在过去给了用户使用approve 功能花费 amount 代币的许可。

现在继续用这个例子。

  • Bob给Alice的NFT合约提供了使用approve 函数花费最多10个他的Alicecoin的许可。
  • Bob调用函数在Alice的NFT合约上购买她的NFT
  • 购买函数在内部调用了AlicecointransferFrom,并将10个Alicecoin从Bob的账户转移到Alice的账户中。
  • 由于该合约在之前被Bob赋予了最多花费10个Alicecoin的权限,所以这个动作是被允许的
  • 因此,Alice收到了她的10个Alicecoin,而Bob收到了他的NFT

这对我们来说意味着什么?

注意一下Bob是如何批准合同的这样合同就可以从他的账户里取走Bob的代币。

因此,Bob 实际上必须执行两个事务,以复制在 ETH 中接受付款时在一个事务中可以执行的行为。

事务1-为契约提供余额

事务2-调用契约函数,该函数在内部使用余额将 Bob 的令牌转移到不同的地址

因此,如果您正在构建一个 dApp,其中您需要用户使用 ERC20令牌支付您的智能合同,那么您还需要让他们同时执行这两个事务。简单地调用您的契约函数,而不首先让您的用户为您的契约提供补贴,将导致函数调用失败。

当我们在课程的最后一级建造DeFi-Exchange的时候,我们会遇到这个流程的一个用例。由于交换涉及到能够转换另一个令牌的一个令牌,因此需要在交换智能契约上调用一个函数,该函数接受一个令牌并给出另一个令牌。

要接受令牌进行交换,交换合同需要获得批准才能从您的帐户中取出令牌。

因此,如果你想知道为什么在交易所交换可以使用两个而不是一个交易,请记住这个流程。

原文:https://www.learnweb3.io/tracks/sophomore/mixed-topics

https://hicoldcat.oss-cn-hangzhou.aliyuncs.com/img/my.png