美文网首页ETHHyperledger
通过小游戏学习Ethereum DApps编程(8)

通过小游戏学习Ethereum DApps编程(8)

作者: 假装在去天使之城的路上 | 来源:发表于2018-09-29 15:14 被阅读3次

    这篇博客是 通过小游戏学习Ethereum DApps编程系列。

    第五章结束

    在第五章里面我们了解了ERC20 tokens,ERC721标准,以及crypto-collectible。这些知识可以让我们和其他玩家交易自己的创造的角色。

    在最后一章节我们将了解怎么把智能合约发不到ETH网络上。我们会了解一些关于Web3.js库的知识点。

    如何从MetaMask获取用户的账号

    MetaMask是一款可以用于Chrome和Firefox的插件,实现了Web3的接口,用于管理用户的private key。
    MetaMask上可以同时管理多个账号。

    获取当前活跃的账号:

    var userAccount = web3.eth.accounts[0]
    

    如果我们的游戏的主页上,有一个显示目前账号拥有的角色的功能的话,在用户切换账号的时候,我们需要重新获取新账号的信息,然后更新显示的结果。

    我们可以通过一个timer来做check。

    var accountInterval = setInterval(function() {
      // Check if account has changed
      if (web3.eth.accounts[0] !== userAccount) {
        userAccount = web3.eth.accounts[0];
        // Call some function to update the UI with the new account
        updateInterface();
      }
    }, 100);
    

    send

    我们可以使用send功能来进行我们角色的交换。

    • send需要我们的账户地址用于智能合约msg.sender的调用
    • send需要消费gas
    • 在我们提出send请求之后,根据我们设定的gas,最终被Blockchain执行并且写入到Block里面,可能有延迟。

    复习:Web3和solidity之间的调用

    在solidity里面,我们可以有这样一个功能:

    function createRandomZombie(string _name) public {
      require(ownerZombieCount[msg.sender] == 0);
      uint randDna = _generateRandomDna(_name);
      randDna = randDna - randDna % 100;
      _createZombie(_name, randDna);
    }
    

    我们可以从Web3这样调用

    function createRandomZombie(name) {
      // This is going to take a while, so update the UI to let the user know
      // the transaction has been sent
      $("#txStatus").text("Creating new zombie on the blockchain. This may take a while...");
      // Send the tx to our contract:
      return cryptoZombies.methods.createRandomZombie(name)
      .send({ from: userAccount })
      .on("receipt", function(receipt) {
        $("#txStatus").text("Successfully created " + name + "!");
        // Transaction was accepted into the blockchain, let's redraw the UI
        getZombiesByOwner(userAccount).then(displayZombies);
      })
      .on("error", function(error) {
        // Do something to alert the user their transaction has failed
        $("#txStatus").text(error);
      });
    }
    

    发送send到Web3服务提供方

    在我们发送send请求到Web3服务方(比如:MetaMask插件),我们可以通过监听来得到结果

    • receipt 表示我们的请求得到了处理,并且完成了Blockchain的写入。
    • error 表示执行没有顺利完成,或许是因为我们没有设定足够的gas等。

    在执行send的时候,我们可以设定一个固定值为gas,当我们没有特别指定一个gas值的时候,MetaMask可以让用户来选择。

    send({ from: userAccount, gas: 3000000 })
    

    Wei

    Wei是表述gas的单位,10^18个wei等于一个ether。

    // This will convert 1 ETH to Wei
    web3js.utils.toWei("1");
    
    cryptoZombies.methods.levelUp(zombieId)
    .send({ from: userAccount, value: web3js.utils.toWei("0.001", "ether") })
    
    

    从Web3监听Solidity的event

    还记得我们如何在solidity里面定义event的么?

    event NewZombie(uint zombieId, string name, uint dna);
    

    我可以这样在Web3上监听时间的触发:

    cryptoZombies.events.NewZombie()
    .on("data", function(event) {
      let zombie = event.returnValues;
      // We can access this event's 3 return values on the `event.returnValues` object:
      console.log("A new zombie was born!", zombie.zombieId, zombie.name, zombie.dna);
    }).on("error", console.error);
    

    indexed

    在上面的监听event的处理的时候,我们会接收到所以的触发,我们需要过滤信息只在该用户的活跃账户的时候显示提示。

    这时候,我们用indexed就可以解决。

    event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
    
    // Use `filter` to only fire this code when `_to` equals `userAccount`
    cryptoZombies.events.Transfer({ filter: { _to: userAccount } })
    .on("data", function(event) {
      let data = event.returnValues;
      // The current user just received a zombie!
      // Do something here to update the UI to show it
    }).on("error", console.error);
    

    events和indexed在需要监听和过滤信息的时候非常方便。

    我们甚至可以监听过去的event

    cryptoZombies.getPastEvents("NewZombie", { fromBlock: 0, toBlock: "latest" })
    .then(function(events) {
      // `events` is an array of `event` objects that we can iterate, like we did above
      // This code will get us a list of every zombie that was ever created
    });
    

    Because you can use this method to query the event logs since the beginning of time, this presents an interesting use case: Using events as a cheaper form of storage.

    在Eth网络上,存储信息是需要花费gas的,如果我们只需要显示信息,我们可以利用event的可追溯功能,来廉价的实现。

    学习完毕

    图片来源

    图片来自原作者官方网站

    相关链接

    HiBlock区块链技术布道 GitHub
    cryptozombies

    相关文章

      网友评论

        本文标题:通过小游戏学习Ethereum DApps编程(8)

        本文链接:https://www.haomeiwen.com/subject/bqmvoftx.html