web3js(2)

158 阅读3分钟

!插播javascript的Promise

2022年8月2日15:06:33 javascript的Promise语法:      let myPromise = new Promise(function(myResolve, myReject) { // "Producing Code"(可能需要一些时间)

      myResolve(); // 成功时
      myReject();  // 出错时
    });

    // "Consuming Code" (必须等待一个兑现的承诺)
    myPromise.then(
      function(value) { /* 成功时的代码 */ },
      function(error) { /* 出错时的代码 */ }
    );

获取MetaMask中的用户账户

获取web3变量中即获当前账户:

    var userAccount = web3.eth.account[0];

应用需要能监控当前账户这个变量,因为用户可以在MetaMask中随意切换账户,而且还要注意,一旦用户切换了账户,我就需要更新相应页面。

用setInterval方法来做:

    var accountInterval = setInterval(function() {
      // 检查账户是否切换
      if (web3.eth.accounts[0] !== userAccount) {
        userAccount = web3.eth.accounts[0];
        // 调用一些方法来更新界面
        updateInterface();
      }
    }, 100);

这段代码是在:每100毫秒检查一次userAccount是否还等于web3.eth.accounts[0]。若不等,则将 当前激活用户赋值给 userAccount,然后调用一个函数来更新界面。

发送事物

用send函数来修改智能合约里的数据

相对 call 函数,send 函数有如下主要区别:

  •  send一个事务需要一个from地址来表明谁在调用这个函数(也就是你 Solidity 代码里的msg.sender)。 我们需要这是我们 DApp 的用户,这样一来 MetaMask 才会弹出提示让他们对事务签名。

  •  send一个事务将花费gas

  •  在用户send一个事务到该事务对区块链产生实际影响之间有一个不可忽略的延迟。这是因为我们必须等待事务被包含进一个区块里,以太坊上一个区块的时间平均下来是15秒左右。如果当前在以太坊上有大量挂起事务或者用户发送了过低的 gas 价格,我们的事务可能需要等待数个区块才能被包含进去,往往可能花费数分钟。

所以在我们的代码中我们需要编写逻辑来处理这部分异步特性。

    function createRandomZombie(name) {
      // 这将需要一段时间,所以在界面中告诉用户这一点
      // 事务被发送出去了
      $("#txStatus").text("正在区块链上创建僵尸,这将需要一会儿...");
      // 把事务发送到我们的合约:
      return cryptoZombies.methods.createRandomZombie(name)
      .send({ from: userAccount })
      .on("receipt", function(receipt) {
        $("#txStatus").text("成功生成了 " + name + "!");
        // 事务被区块链接受了,重新渲染界面
        getZombiesByOwner(userAccount).then(displayZombies);
      })
      .on("error", function(error) {
        // 告诉用户合约失败了
        $("#txStatus").text(error);
      });
    }

我们的函数send一个事务到我们的 Web3 提供者,然后链式添加一些事件监听:

  •   receipt 将在合约被包含进以太坊区块上以后被触发,这意味着僵尸被创建并保存进我们的合约了。

  •  error 将在事务未被成功包含进区块后触发,比如用户未支付足够的 gas。我们需要在界面中通知用户事务失败以便他们可以再次尝试。

注意:你可以在调用 send 时选择指定gasgasPrice, 例如: .send({ from: userAccount, gas: 3000000 })。如果你不指定,MetaMask将会让用户自己选择数值。

先写这么多。