草庐IT

以太坊Solidity迁移Flow Cadence指南8-ERC721/NFT迁移

wangliang_f 2025-02-19 原文

序言

本小节是本系列短文的核心章节,主要介绍如何将solidity标准的ERC721合约迁移到flow cadence,大家前面也学了这么多了,就看这一节了!!!

什么?前面几节都没看到。本来2022.5月就要写完的,结果5月笔者一直足不出户在家办公,主要在研究如下内容:

 

图 1 用做菜的思路迁移代码

笔者发现,有一种叫做“预制菜”的东西,不用开荒种地,不用掌握油盐酱醋配比,锅里一放,简单炒炒就是等级厨师的作品了。。。

嗯,solidity ----> cadence 迁移是否也能采用“预制菜”模式呢?

给你想要的!填写你的以太坊ERC721合约地址,然后你就能得到:

1 Solidity ERC721合约对应的cadence 合约代码。

2 Cadence 合约相关的transaction代码和script代码。

3 可以调用Cadence 的vue.js 模板代码。

4 登录flow钱包,即可将生成的cadence直接部署到flow测试网或正式网。

5 将已经铸造的NFT全部迁移到flow对应合约中,默认存放在合约地址内。

访问cook.flow.study  

本节。。。。。。。。。。完。

不写代码,才是有理想的码农的理想。能来看Flow合约的,肯定都是有理想的。那就继续看看怎么才能做到:)

标准ERC721合约分析

大部分的以太坊NFT合约大致是这样的:

pragma solidity ^0.8.2;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract WowNFT is ERC721 {

  constructor() ERC721("WOW", "WOW") {}

}

也就是说,编写包含主要功能Solidity合约,只需要一行代码:

 constructor() ERC721("WOW", "WOW") {} //定义nft的名称和简称

其他部分都是引用的标准代码,如果需要扩充功能,好比扩充燃烧功能,引用一个新模块即可:

import "@openzeppelin/contracts/token/ERC721/ERC721Pausable.sol";

目前openzeppelin等都开发了各种围绕ERC721的扩展,这些就是solidity的NFT合约开发“预制菜”。

对应的,如果要实现cadence NFT的“预制菜”,只需要找到或者实现类似openzeppelin开发的这些基础合约就行了。这个就是我们迁移的基本思路。

实际上,Cadence上已经有类似的基础标准合约,是以flow 参考元数据标准开发的。我们以openzeppelin对应实现的基础ERC721合约为准(https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol),对应的为Flow推荐的元数据标准合约实现(https://github.com/onflow/flow-nft),然后找到对齐关系,看需要修改的Cadence继承实现代码即可。这里暂时不考虑各种合约扩展功能。

数据结构

按照程序分析的一般套路,还是先分析数据结构,然后再看对应的增删改查功能函数。

ERC721和Flow推荐NFT标准合约数据结构对应关系如下图所示:

 

图2 ERC721和flow nft标准合约数据结构对应图

ERC721和Flow NFT合约定义NFT的基础都是一个唯一的数字id,对应的元数据则有所不同,由于Flow存储较为便宜,因此,标准合约还将具体的NFT名称、描述、缩略图链接也存放在链上,而ERC721则主要通过一个链接来存放更详细的元素局。

solidity指向元数据的链接内容要求为json格式,链接形式一般如:

https://opensea.mypinata.cloud/ipfs/QmYjhUCiQrYZCZNRk2wNbfuNgJF6Aan1dmnydPYjyS6DQ1/8686

也就是这样 “主链接+ nft id” 的形式

具体的数据格式标准,一般采用ERC721元数据标准 schema,或者扩展类型的ERC-1155元数据标准,具体如下:

{

    "title": "Token Metadata",

    "type": "object",

    "properties": {

        "name": {

            "type": "string",

            "description": "Identifies the asset to which this token represents"

        },

        "decimals": {

            "type": "integer",

            "description": "The number of decimal places that the token amount..."

        },

        "description": {

            "type": "string",

            "description": "Describes the asset to which this token represents"

        },

        "image": {

            "type": "string",

            "description": "A URI pointing to a resource with mime type image/*."

        },

        "properties": {

            "type": "object",

            "description": "Arbitrary properties. Values may be strings, numbers, object or arrays."

        }

    }

}

一个典型的NFT元数据例子如下所示:

{

  "id": 8686,

  "name": "Tidal Guiltless",

  "description": "Because a TPL Rig is wired directly...",

  "external_url": "https://cyberbrokers.io/",

  "image": "https://cyberbrokers-api-images.s3.amazonaws.com/41e3b1da4635764f4a9fb9a580414d792a4490cc2729176c635974659712b84b.svg",

  "attributes": [

    {

      "trait_type": "Talent",

      "value": "Dealer"

    },

    {

      "trait_type": "Body",

      "value": 14

    }

  ]

}

而Flow NFT的扩展元数据,链接格式一般也是:

"https://example-nft.onflow.org/".concat(self.id.toString())

和ERC721类似,也是“主链接+ nft id” 的形式,而链接存储的内容,目前flow社区暂时没有具体的标准,一般建议也使用ERC-1155元数据标准。但因为Flow的存储空间非常便宜,也1个Flow就能租用100M的存储空间,因此,很多Flow NFT合约是将全部的元数据都存在了链上,而扩展元数据只存储图片的链接。

功能函数

ERC721和Flow推荐NFT标准合约的功能函数对应关系如下图所示:

 

图3 ERC721和Flow功能结构对应图

和ERC20类似,Flow NFT合约并不提供Approve相关的三方托管功能,只需要编写mint/铸造,transfer/转移,getids/查询用户nft。

合约迁移

从数据结构和功能函数来看, Solidity ERC721标准合约和flow cadence NFT合约都存在完整的对应关系,具体迁移的时候,只需迁移核心的mint和transfer功能即可,approve的功能可以忽略,保留核心功能就行。Flow相关的approve托管合约,可通过solidity类似的中性化试试,也可以利用“能力”相关的功能实现,具体可参考NFT市场一节。

根据上的叙述,对于标准NFT合约的迁移,我们只需要对flow合约进行“字符串替换”即可,具体如下图所示:

 

图4 ERC721合约迁移具体流程

如上图所示,核心就是修改合约名称,代码中对应合约名称的引用部分,也进行对应的修改即可。包括合约、交易、脚本都按此修改即可。合约部分有资源集接口,也进行对应的字符串修改即可。另外还有包含NFT名称的资源路径和函数名称,替换成新的合约名称字符串即可。

熟悉linux shell脚本的同学,使用一句shell脚本即可完成上面所说的替换:

#!/bin/sh

nft_name="Wow" #NFT名称

find ./ -name "*.cdc"|xargs -i sed 's/Example/'''${nft_name}'''/g' {}

物品迁移

ERC721的NFT物品迁移,只需要根据Solidity铸造的NFT id列表,使用flow NFT的铸造脚本进行铸造即可。

元数据方面,除了flow NFT标准元数据中包含的name, description,thumbnail 外,Solidity中扩展元数据部分,也可以放到flow NFT合约中即可,如存放attributes的属性例子:

 "attributes": [

    {

      "trait_type": "Talent",

      "value": "Dealer"

    },

    {

      "trait_type": "Body",

      "value": 14

    }

 ]

其包括Talent,Body两个属性,可以在flow合约中设置一个专门的结构体:

pub struct WowMetadata {

        pub let Talent:String

        pub let Body: Int

}

然后在NFT资源中使用即可:

pub resource NFT: NonFungibleToken.INFT, MetadataViews.Resolver {

pub let id: UInt64

    pub var metadata:WowMetadata? //使用自定义的结构体

case Type<WowNFT.WowMetadata>(): //解析部分

          if let meta = self.metadata {

                return MagicWar.MagicWarMetadata(

                            Talent:meta.name,

                            Body:meta.Body

)

}

}

用户迁移

这个。。。,应该有神马跨链技术啥的,笔者不懂,感觉也没必要。目前大部分以太坊NFT应用的用户量,也就是flow nba top shot的零头,Flow元宇宙才是星辰大海。

BTW

目前cook.flow.study还只提供基础的Cadence NFT合约自动生成功能,就是按照上面说的,进行字符串替换,但大部分NFT应用也就够用了。后续会逐步拓展盲盒功能、多管理员功能等“预制菜”模块。因为笔者是专业是AI的,后续也会引入一些AI编程的功能,项目名字就叫 flow cook。有感兴趣的小伙伴可以来github上参与了:)

Playground: Flow Playground

Github(本节):GitHub - maris205/flow-is-best: flow cadence learning code. from solidity to cadence

Flow cook: https://github.com/maris205/flow-cook

有关以太坊Solidity迁移Flow Cadence指南8-ERC721/NFT迁移的更多相关文章

  1. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby-on-rails - 在现有数据库上进行 Rails 迁移 - 2

    我正在创建一个新的Rails3.1应用程序。我希望这个新应用程序重用现有数据库(由以前的Rails2应用程序创建)。我创建了新的应用程序定义模型,它重用了数据库中的一些现有数据。在开发和测试阶段,一切正常,因为它在干净的表数据库上运行,但是当尝试部署到生产环境时,我收到如下消息:PGError:ERROR:column"email"ofrelation"users"alreadyexists***[err::localhost]:ALTERTABLE"users"ADDCOLUMN"email"charactervarying(255)DEFAULT''NOTNULL但是我在迁移中有这

  4. ruby-on-rails - Rails 迁移中的 PostgreSQL 点类型 - 2

    我想使用PostgreSQL中的point类型。我已经完成了:railsgmodelTestpoint:point最终的迁移是:classCreateTests当我运行时:rakedb:migrate结果是:==CreateTests:migrating====================================================--create_table(:tests)rakeaborted!Anerrorhasoccurred,thisandalllatermigrationscanceled:undefinedmethod`point'for#/hom

  5. Ruby 和指南针路径与 yeoman 项目 - 2

    我安装了ruby​​、yeoman,当我运行我的项目时,出现了这个错误:Warning:Running"compass:dist"(compass)taskWarning:YouneedtohaveRubyandCompassinstalledthistasktowork.Moreinfo:https://github.com/gruUse--forcetocontinue.Use--forcetocontinue.我有进入可变session目标的路径,但它不起作用。谁能帮帮我? 最佳答案 我必须运行这个:geminstallcom

  6. ruby-on-rails - Rails 3 : belongs_to, has_one 和迁移 - 2

    我是Rails的新手,我是从Django背景开始接触它的。我已经接受了这样一个事实,即模型和数据库模式在Rails和在线Django中是分开的。但是,我仍在努力处理迁移。我的问题很简单-如何使用迁移向模型添加关系?例如,我现在有Artist和Song作为ActiveRecord::Base子类的空模型,没有任何关系。我需要开始做这件事:classArtist但是我如何使用railsgmigrate更改架构以反射(reflect)这一点?我正在使用Rails3.1.3。 最佳答案 现在,在Rails4中,您可以:classAddPro

  7. ruby-on-rails - Rails 4 从迁移索引中删除迁移 ID - 2

    如何在rakedb:migrate:status中删除带有“**NOFILE**”的迁移ID列表?例如:StatusMigrationIDMigrationName--------------------------------------------------up20131017204224Createusersup20131218005823**********NOFILE**********up20131218011334**********NOFILE**********我不明白为什么当我自己手动删除它时它仍然保留旧的迁移文件,因为我正在研究迁移的工作原理。这是为了记录吗?但

  8. 玩以太坊链上项目的必备技能(初识智能合约语言-Solidity之旅一) - 2

    前面一篇关于智能合约翻译文讲到了,是一种计算机程序,既然是程序,那就可以使用程序语言去编写智能合约了。而若想玩区块链上的项目,大部分区块链项目都是开源的,能看得懂智能合约代码,或找出其中的漏洞,那么,学习Solidity这门高级的智能合约语言是有必要的,当然,这都得在公链``````以太坊上,毕竟国内的联盟链有些是不兼容Solidity。Solidity是一种面向对象的高级语言,用于实现智能合约。智能合约是管理以太坊状态下的账户行为的程序。Solidity是运行在以太坊(Ethereum)虚拟机(EVM)上,其语法受到了c++、python、javascript影响。Solidity是静态类型

  9. Simulink方法总结和避坑指南(一)——Simulink入门与基本调试方法 - 2

    文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景  最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。  在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记

  10. ruby - Ruby gems 的问题(损坏?)试图让指南针在 npm 中工作 - 2

    我不是Ruby专家,但想弄清楚发生了什么,因为我试图让指南针在节点应用程序中工作,但我的Ruby似乎坏了。打字:ruby--version让我:ruby2.1.1p76(2014-02-24revision45161)[x86_64-darwin13.0]我安装了Homebrew,之前遇到过Ruby版本的问题,但它似乎已安装并且可以正常工作。但是,当我使用gem输入请求时,出现此错误:$gem-hErrorloadingRubyGemsplugin"/Users/user_dir/.rvm/gems/ruby-2.1.1@global/gems/executable-hooks-1.3

随机推荐