全链游戏,简而言之,就是将游戏的所有核心逻辑,包括状态存储、计算与执行等,全部部署于区块链上。直观来说,现有的区块链技术一定是无法满足大部分游戏的部署需求。
正如我们所熟知的,游戏开发首先需要一套引擎,例如unity,或者unreal引擎。游戏引擎并非必须,但如果从头自己开发一部游戏作品,是中小型开发者所无法承担成本的一种选择(对于大厂来说,出于竞争、定制化需求以及效率提升的缘故,他们有动机开发自己的引擎,例如Rockstar开发了自己的引擎RAGE)。
另一个必不可少的基础设施,是云计算服务。诸如AWS、Google Cloud、Microsoft Azure等,可以实现游戏开发、构建、测试、发布、部署全流程全链条的托管,对游戏开发效率的提升是数量级式的;云计算同时在资源与带宽共享、即时和动态后端支持等多方面实现更好的效果。
游戏对计算的要求极高,大部分游戏均有客户端与服务器长连接、网络低延迟、频繁的数据写入(并发读写)、玩家交互、承载弹性等各类计算能力需求。并发读写、低延时、极高的tps要求,这些都决定了现阶段甚至未来的区块链技术,本身很难承担游戏计算的职责。
假使不考虑计算,仅考虑存储,当前一款普通的游戏,游戏本身几个G到上百G的容量,加上运存要求,也并非当前区块链所能承受的范围。ETH自2015年,全部交易历史在标准模式下大约是1TB,这仅仅相当于十几部大型游戏的容量。
普通链游、传统游戏之间的对比
如前所述,链游市场经历了最初一波的火热与沉寂后,很多传统游戏产业的开发者加入,新一代的链游在游戏质量与可玩性上将有极大提升,且经济模型设计也将有优化。为了便于区分,笔者将它们分别称为“初代链游”与“二代链游”。
NFT智能合约代码,我们基于OpenZeppelin库的ERC-721实现。复制并粘贴以下内容到你的MyNFT.sol文件中:
//Contract based onhttps://docs.openzeppelin.com/contracts/3.x/erc721
//SPDX-License-Identifier:MIT
pragma solidity^0.8.0;
import"openzeppelin/contracts/token/ERC721/ERC721.sol";
import"openzeppelin/contracts/utils/Counters.sol";
import"openzeppelin/contracts/access/Ownable.sol";
import"openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
contract MyNFT is ERC721URIStorage,Ownable{
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
constructor()ERC721("MyNFT","NFT"){}
function mintNFT(address recipient,string memory tokenURI)
public onlyOwner
returns(uint256)
{
_tokenIds.increment();
uint256 newItemId=_tokenIds.current();
_mint(recipient,newItemId);
_setTokenURI(newItemId,tokenURI);
return newItemId;
}
}
因为我们要从OpenZeppelin合约库中继承基础合约类,在你的命令行中运行npm install openzeppelin/contracts来把这个库安装到我们的工程中。
那么,上面这段代码到底做了什么?让我们逐行分解:
在我们的智能合约的顶部,我们导入了三个OpenZeppelin智能合约类:
openzeppelin/contracts/token/ERC721/ERC721.sol包含ERC-721标准的实现,我们的NFT智能合约将继承这个标准。(要成为一个有效的NFT,你的智能合约必须实现ERC-721标准的所有方法)。要了解更多关于继承的ERC-721功能,请查看接口定义这里。
openzeppelin/contracts/utils/Counters.sol提供了只能加1或减1的计数器。我们的智能合约使用计数器来跟踪已铸币的NFT总数,并在我们的新NFT上设置唯一的ID。(每个使用智能合约铸造的NFT必须被分配一个唯一的ID--在本文案例中,我们的唯一ID只是由存在的NFT总数决定。例如,我们用智能合约铸造的第一个NFT的ID是1,我们的第二个NFT的ID是2,等等)。
openzeppelin/contracts/access/Ownable.sol在我们的智能合约上设置了访问控制,所以只有智能合约的所有者(你)可以铸币NFT。(注意,包括访问控制完全是一种偏好。如果你希望任何人都能使用你的智能合约铸造NFT,请删除第10行的Ownable一词和第17行的onlyOwner)。
在我们的导入语句之后,我们有了自定义的NFT智能合约,它出乎意料地短--它只包含一个计数器、一个构造函数和一个函数!这要归功于我们继承的OpenZeppelin合约,它实现了我们需要创建NFT的大部分方法,,例如ownerOf,它返回NFT的所有者,以及transferFrom,它将NFT的所有权从一个账户转移到另一个账户。
在我们的ERC-721构造函数中,你会注意到我们传递了两个字符串,MyNFT和NFT。第一个变量是智能合约的名称,第二个是其符号。你可以随心所欲地给这些变量命名!
最后,我们有我们的函数mintNFT(address recipient,string memory tokenURI),用来铸造一个NFT,你会注意到这个函数接收了两个变量:
address recipient指定将收到你新铸的NFT的地址
string memory tokenURI是一个字符串,应该解析为一个描述NFT元数据的JSON文档。NFT的元数据实际上是给它带来生命的东西,允许它有可配置的属性,如名称、描述、图像和其他属性。在本教程的第二部分,我们将描述如何配置这个元数据。
mintNFT从继承的ERC-721库中调用一些方法,并最终返回一个数字,代表新铸造的NFT的ID。