九层天塔 DApp 合约系统开发搭建
全链游戏的乐趣应该是:在区块链上构筑稳固、不可篡改的核心玩法,并将衍生玩法的设计最大限度地让渡给玩家,使得游戏衍生本身能产生无数的可能,内容再次创作有无限的延展性。九层天塔 DApp 系统开发询 13z 李 4277 森 z558,九层天塔模式开发技术。
创作一款好玩的全链游戏,设计者要 try to play god(当然是一个有趣的 god),造一个有趣的世界,具体来说分三步:
1)提炼出游戏的核心玩法,明确有哪些要素是希望刻进游戏 dna 里,不希望任何人(包括作者)能改变的,然后将核心玩法拆分成最小的原子
2)将游戏原子用区块链变成玩家的共识,成为游戏世界运行的底层规则
3)用合理的设计鼓励人类用这些原子去创造更有趣更丰富的世界。
我们来想象一下:
1)将核心玩法拆分成最小的原子。假设我们要设计一款中古题材的生存建造类全链游戏,游戏的核心玩法就是 crafting:a+b=c,分析下来就是,在游戏中制作的物品根据它们所使用的资源继承属性,然后这些物品可以以某种方式被命名,以使游戏的其他要素可以对它们作出反馈。
我们决定将 crafting 这部分逻辑放进智能合约,和中心化服务器中存储的游戏逻辑不同,所有人都可以了解并验证这些逻辑,这部分游戏就如同是这个世界运行的物理定理,不以任何人的意志为转移。
2)将游戏原子用区块链变成玩家的共识,成为游戏世界运行的底层规则。接着我们去定义一个世界,这个世界上存在 5 种元素,LIFE(血)ATTACK(攻击)DEFENCE(防御)SPEED(速度)BULK(体积)。
从消费者到创造者,站在玩家视角漫谈全链游戏设计
这可能是一个非常简单的 smart contract:输入木材,输出盾牌。但背后隐藏着这个世界的物理法则——
1.物品和物品可以被合成新的物品
2.木头(defense)是可以抵挡攻击(attack)的。这个物理法则是不可篡改的,是所有玩家都需要 respect 的。
但是要如何利用它——到底是将其附着在某个建筑上并命名这个叫武器工厂,还是将它附着在一个 npc 身上,将这个 npc 命名为女武神——同样能用魔法将木头变成名为所罗门的盾牌。那就交给玩家创作了。
智能合约不仅限于制作物品。作为游戏中的玩家,我想写一个关于圣盾的子故事。这可以使用含有大量 BULK 原子的材料创建一座建筑——堡垒。在这堵墙上附加一个 smart contract,只允许携带名为所不朽圣盾的盾牌的过去的玩家通过。这样不朽圣盾除了在战斗中有用之外,还具有其他实用性。此外,这些物品本身可以用于制作新的物品,因此 10 个不朽之盾和一颗女巫牙可以参加一个抽奖,抽奖有概率开出上古之戒,让持有者通过继承的 SPEED 元素获得地图上的道路地图。
说了 NFT 的独特,那我们再来谈谈它是怎么被铸造的,基于什么逻辑实现它的独一无二。
以下非同质化代币的铸造分析,原始代码参考以太坊 ERC721 提案。
首先非同质化代币的铸造会执行
_safeMint 函数,该函数存在两个参数,他们分别的作用是:
to:新铸的代币接受地址
tokenId:新铸代币的 id 序列
function _safeMint(address to,uint256 tokenId)internal virtual{
_safeMint(to,tokenId,"");//接收以上两个参数加上空字符凑齐 3 个参数传入同名_safeMint 函数(重载)
}
可以看到接下来调用三参数同名_safeMint 函数,
function _safeMint(address to,uint256 tokenId,bytes memory _data)internal virtual{//接收_safeMint 函数传参
_mint(to,tokenId);//将传参 to 和 tokenId 传入_mint 函数
require(_checkOnERC721Received(address(0),to,tokenId,_data),"ERC721:transfer to non ERC721Receiver implementer");//调用_checkOnERC721Received 函数来检测函数接口合法性
}
最后调用_mint 函数进行铸币:
function _mint(address to,uint256 tokenId)internal virtual{//接收来自_safeMint 函数的传参
require(to!=address(0),"ERC721:mint to the zero address");//校验传参地址是否为空(为假继续后续操作,为真终止操作)
require(!_exists(tokenId),"ERC721:token already minted");//接着校验 tokenId 是否已经存在(为假继续后续操作,为真终止操作)
_beforeTokenTransfer(address(0),to,tokenId);//初始化;
_balances[to]+=1;//在传参地址 to 上生成一个 token
_owners[tokenId]=to;//将传参地址 to 与引索 tokenId 进行绑定
emit Transfer(address(0),to,tokenId);//触发 token 生成事件
}
就这样一个独一无二的 NFT 被铸造出来了。总体过程如下:
合约中使用_safeMint 函数调用铸币函数并检查函数的 ERC721 函数接口合法性,该函数在 ERC721 中有所体现,代码如下:
function _checkOnERC721Received(address from,address to,uint256 tokenId,bytes memory _data)
private returns(bool)
{
if(to.isContract()){
try IERC721Receiver(to).onERC721Received(_msgSender(),from,tokenId,_data)returns(bytes4 retval){
return retval==IERC721Receiver(to).onERC721Received.selector;
}catch(bytes memory reason){
if(reason.length==0){
revert("ERC721:transfer to non ERC721Receiver implementer");
}else{
//solhint-disable-next-line no-inline-assembly
assembly{
revert(add(32,reason),mload(reason))
}
}
}
}else{
return true;
}
}
在_mint 函数中首先检查了地址是否是 0 地址,还有 tokenId 是否已存在。该 tokenId 在 ERC721 标准中生成规则是一个不可互换的通证。检测通过后为 to 地址铸币(相应的 tokenId),同时记录余额与该 NFT 艺术品的归属者
评论