美文网首页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