天品互联

如何在 ALGORAND 上开发 NFT 系统?

编辑时间:2022-06-26  浏览次数:0

FIFA 最近的一项声明席卷了区块链社区:它与区块链创新者 Algorand 建立了合作关系。区块链协议 Algorand 旨在帮助 FIFA 制定“数字资产战略”并提供官方“钱包解决方案”。

这不是 Algorand 第一次与大型项目合作。此前,马绍尔群岛联邦政府宣布与 Algorand 合作创建其第一个国家货币 SOV,这也是世界上第一个国家货币。同样,还有其他几项合作公告,例如 FIDE Grand Prix 系列(世界国际象棋锦标赛)、SIAE(意大利集体版权管理公司)、Republic(投资平台和技术服务)等等。所有这些合作伙伴关系的公告证明,Algorand 已成为区块链领域可靠的区块链生态系统。

Algorand 由 Silvio Micali 领导的团队于 2017 年推出,他是图灵奖获得者,因其在 2012 年对密码学的贡献而获得认可。他是可验证随机证明、零知识证明等各种密码技术的共同创造者。

Micali 认为区块链协议可以同时实现去中心化、可扩展性和安全性,而不会牺牲其中任何一个,正如以太坊创始人 Vitalik Buterin 在 2016 年提出的那样。这激发了 Micali 创建 Algorand,这是一个无需许可的区块链,旨在解决多年来让区块链社区困惑的区块链三难困境。它是一个面向智能合约的平台,无需分叉即可提供即时交易最终确定性。Algo 是 Algorand 的原生加密货币,用于质押、治理和交易。

本文提供了对 Algorand 的深入了解,并详细说明了在 Algorand 上开发 NFT 市场的步骤。

  • 关于 Algorand

  • 如何在 Algorand 上开发 NFT 市场?

    • 第 1 步:定义有状态智能合约接口

    • 第 2 步:实施有状态的智能合约

    • 第3步:实现无状态智能合约

    • 第4步:通讯服务

    • 第 5 步:部署 Algorand 测试网

关于 Algorand

Algorand 是一个区块链生态系统,它在称为纯权益证明的独特共识机制上运行,使其能够处理多达 1000 笔交易并提供即时交易最终确定性而无需分叉。Pure Proof-of-Stake 有两种类型的节点:参与者节点和中继节点。顾名思义,参与者节点参与共识,而中继节点则支持参与者节点之间的交互。在 Pure Proof-of-Stake 中,随机选择 1000 个参与者节点来生成一个块,从中随机选择一个节点将其块添加到 Algorand 区块链中。被选中取决于参与者节点质押了多少 Algo。质押的 Algo 数量越多,被选中的机会就越大。

Algorand 网络包含三个关键功能:

  • Algorand 标准资产——它是第 1 层功能,允许用户代表 Algorand 区块链上的任何资产,同时受益于 Algo 的安全性、兼容性、速度和易用性。

  • Algorand Atomic Transfer –这些是不可约的批量交易,可保证同时执行任何资产的多个交易。

  • 智能合约——Algorand 提供直接构建在第 1 层区块链上的高度可定制的智能合约。

Algorand 智能合约可分为以下几类:

  • 有状态的智能合约:它们可以存储和更新链上值并实现应用程序逻辑。

  • 无状态智能合约:它们经常用于批准支出或资产转移,并且它们管理来自单个账户的所有交易。

现在我们对 Algorand 基础设施有了一个概念,让我们来看看 Algorand NFT 市场的开发。

如何在 Algorand 上开发 NFT 市场?

在您的 Python 环境中安装下面提到的软件包:

  • PyYAML

  • py_algorand_sdk

  • pyteal

  • 流线型

此外,创建一个“config.yml”文件,您必须在其中添加凭据以连接 Algorand 客户端。

帐户:

帐户_1:

地址:PUBLIC_KEY_VALUE

助记符:MNEMONIC_WORDS

private_key:PRIVATE_KEY_VALUE

帐户_2:

地址:PUBLIC_KEY_VALUE

助记符:MNEMONIC_WORDS

private_key:PRIVATE_KEY_VALUE

帐户_3:

地址:PUBLIC_KEY_VALUE

助记符:MNEMONIC_WORDS

private_key:PRIVATE_KEY_VALUE

总数:3

客户凭证:

地址:ADDRESS_VALUE

令牌:TOKEN_VALUE

第 1 步:定义有状态智能合约接口

有状态的智能合约代表一个存在于 Algorand 网络上的应用程序。应用程序调用事务促进了用户和应用程序之间的交互。目前,交易是由用户界面应用程序、移动应用程序、Web 应用程序或 CLI 通过网络创建和发送的。

首先,概述一个涉及所有必需方法的“NFTMarketplaceInterface” 。这些方法描述了外部应用程序和有状态智能合约之间的交互。

NFTMarketplaceInterface类(ABC ):

   @抽象方法

def initialize_escrow ( self, escrow_address ) :

       经过

   @抽象方法

def make_sell_offer (自我,sell_price ):

       经过

   @抽象方法

def购买(自我):

       经过

   @抽象方法

def stop_sell_offer (自我):

       经过

一个抽象的python类用于表示接口。该接口中描述的所有方法都必须由想要遵守它的智能合约实现。需要注意的是,这个接口可以被多个智能合约使用,每个智能合约可以有不同的实现逻辑。尽管有单独的实现逻辑,但外部通信不会改变。

在“NFTMarketplaceInterface”中,定义了四个方法:

  • “initialize_escrow(escrow_address)”——初始化用于传输 NFT 的托管地址。

  • “make_sell_offer(sell_price)”——它以特定的“sell_price”为 NFT 生成卖出报价。

  • “buy()”——用户从卖出报价中购买 NFT

  • “stop_sell_offer()”——取消当前的 NFT 卖出报价。

第 2 步:实施有状态的智能合约

接下来,我们必须构建一个名为“NFTMarketplaceASC1”的具体类,它执行“NFTMarketplaceInterface”。此类将存储有状态智能合约的所有 PyTeal 逻辑。

定义常量

每个有状态的智能合约都可以具有全局和本地状态,形成应用程序状态数据。键值对用于表示这些状态。将键定义为常量是一种很好的做法,它可以使代码更易于阅读且不易出错。此外,模式还指定键值对中使用的整数和字节数。全局状态有一个全局模式,本地状态有一个本地模式。

NFTMarketplaceASC1类(NFTMarketplaceInterface ):

类变量:

       escrow_address =字节(“ESCROW_ADDRESS” )

       asa_id =字节(“ASA_ID” )

       asa_price =字节(“ASA_PRICE” )

       asa_owner =字节(“ASA_OWNER” )

       app_state =字节(“APP_STATE” )

       app_admin =字节(“APP_ADMIN” )

类AppMethods:

       initialize_escrow = "初始化托管"

       make_sell_offer = "makeSellOffer"

       买= “买”

       stop_sell_offer = "stopSellOffer"

类应用程序状态:

       not_initialized = Int ( 0 )

       活跃 = Int ( 1 )

       sell_in_progress = Int ( 2 )

   @财产

def global_schema ( self ) :

返回algosdk。未来。交易。StateSchema ( num_uints= 3 ,

                                                     num_byte_slices= 3 )

   @财产

def local_schema (自我):

返回algosdk。未来。交易。StateSchema ( num_uints= 0 ,

                                                     num_byte_slices= 0 )

我们将常量分解为不同的类,以使代码更具可读性和可维护性:

  • “变量”——指定智能合约全局变量的键。这些变量代表应用程序的全局状态。

  • “AppMethods”——指定允许智能合约与外部应用程序通信的所有方法。此类中的每个常量都必须映射到特定接口中定义的不同方法。

变量

合约由六个全局变量、三个整数和三个字节组成。

  • “escrow_address”——包括负责 Algorand 标准资产(ASA)转移的无状态智能合约的地址,即 NFT。

  • “asa_id”——这是 NFT 的唯一标识符。智能合约负责买卖该id对应的NFT。

  • “asa_price”——当卖出报价有效时,这是 NFT 的价格。

  • “asa_owner”——包含 NFT 的当前所有者地址。只有这个地址才能对 NFT 发出卖出要约。

  • “app_admin” -它包含管理员的地址。只有这个地址才能通过调用“initialize_escrow”方法设置“escrow_address”。

  • “app_state” –它代表 AppState 类的潜在应用程序状态之一。

    以下是三种可能的结果:
  • “not_initialized”——智能合约在网络上启动,但托管尚未初始化。当合约处于这种状态时,只能使用“initialize_escrow”方法。

  • “活跃”——合约已链接到“asa_owner”和 NFT。但是,NFT 仍未出售,表明所有者尚未提供出售。

  • “ sell_in_progress” – NFT 已被所有者出售。当应用程序处于此状态时,买家可以使用“购买”方法购买 NFT。

应用方法

“ NFTMarketplaceInterface”有四种方法,由有状态智能合约实现。结果,创建了一个“AppMethods”类,它唯一地标识了这些方法:

  • “initialize_escrow”——配置智能合约的“escrow_address”。
    按照逻辑,只有“app_admin”地址的应用调用才能调用该方法。此外,“escrow_address”只能初始化一次。

  • “make_sell_offer”——要以“asa_price”微算法的固定价格出售 NFT , “asa_owner”地址可以使用此方法。

  • “购买”——一旦 NFT 发售,购买者就可以使用这种方法购买 NFT。

  • “stop_sell _offer”—— “asa_owner”可以使用此方法结束 NFT 当前的销售报价。

应用程序的初始化

我们需要三个必需的参数来在网络上部署应用程序:

  • 当前拥有 NFT 的地址

  • 在应用程序中具有管理员权限的地址

  • NFT 的 ID

“ asa_owner”和“app_admin”作为应用程序参数发送,而“asa_id”传输到“ApplicationCreateTxn”的“foreign_assets”字段。

def app_initialization (自我):

返回序列([

断言(Txn.application_args.length ()== Int (2 )),_

        应用程序。globalPut ( self.Variables.app_state , self.AppState.not_initialized ) , _ _ _ _ _

        应用程序。globalPut ( self.Variables.asa_id , Txn.assets [ 0 ] ) , _ _

        应用程序。globalPut ( self.Variables.asa_owner , Txn.application_args [ 0 ] ) , _ _

        应用程序。globalPut ( self.Variables.app_admin , Txn.application_args [ 1 ] ) , _ _

返回( Int ( 1 ))

])

初始化托管

应用部署成功后,管理员必须首先调用“initialize_escrow”方法设置负责发送NFT的无状态合约。我们通过将无状态智能合约的地址作为 NFT 的回拨地址来实现这一点。

我们希望确保在与此方法交互时,NFT 的所有属性都符合预期。

  • NFT 不应有管理地址。有了这个条件,我们就排除了修改 NFT 的回拨地址的选项。因为我们在有状态的智能合约中使用和存储回拨地址,所以我们希望它是一致的。

  • 我们检查 NFT 的回拨地址是否与我们作为参数提供的托管地址相同。

  • NFT 应该被冻结,否则 NFT 可能会被发送到任何地址,而“asa_owner”状态变量保持不变。

def initialize_escrow ( self, escrow_address ) :

       curr_escrow_address = 应用程序。globalGetEx ( Int ( 0 ) , self. Variables . escrow_address )

       资产托管=资产参数。回拨(Txn.assets [ 0 ] )

       manager_address = AssetParam。经理(Txn.资产[ 0 ])

       freeze_address = AssetParam。冻结(Txn.assets [ 0 ] )

       保留地址 = 资产参数。储备(Txn.资产[ 0 ])

       default_frozen = AssetParam。defaultFrozen ( Txn.assets [ 0 ] )

返回序列([

           curr_escrow_address,

断言(curr_escrow_address.hasValue ()== Int (0 )),

断言(App.globalGet (self.Variables.app_admin )== Txn.sender ()),_ _

断言( Global.group_size ( ) == Int ( 1 )) ,

           资产托管,

           经理地址,

           冻结地址,

           保留地址,

           默认冻结,

断言(Txn.assets [ 0 ] == App.globalGet (self.Variables.asa_id )),_ _ _

断言(asset_escrow.value ( ) == Txn.application_args [ 1 ] ),

断言( default_frozen.value ( )) ,

断言( manager_address.value () == Global.zero_address ( )) ,

断言( freeze_address.value () == Global.zero_address ( )) ,

断言( reserve_address.value () == Global.zero_address ( )) ,

           应用程序。globalPut (自我。变量。escrow_address ,escrow_address ),

           应用程序。globalPut ( self.Variables.app_state , self.AppState.active ) , _ _ _ _ _

返回( Int ( 1 ))

])

管理员成功初始化托管后,应用程序切换到“AppState.active”状态。现在将允许“asa_owner”出价出售 NFT。

提出购买报价。

NFT 通过卖出报价出售,应用程序只能由 NFT 所有者访问以发起卖出报价。方法名称和 NFT 价格作为参数包含在应用程序调用事务中。此应用程序的内部状态将通过此应用程序调用从“AppState.active”更改为“AppState. sell_in_progress” 。

def make_sell_offer (自我,sell_price ):

       valid_number_of_transactions = 全球。group_size () ==整数( 1 )

app_is_active        =或( App.globalGet ( self.Variables.app_state ) == self.AppState.active , _ _ _ _ _

                          应用程序。globalGet ( self.Variables.app_state ) == self . _ 应用状态。销售进度)

       有效卖家 = Txn。发件人()==应用程序。globalGet (自我。变量。asa_owner )

       valid_number_of_arguments = Txn。应用程序参数。长度() ==整数( 2 )

       can_sell =和( valid_number_of_transactions,

                      app_is_active,

                      有效卖家,

                      valid_number_of_arguments )

       update_state =序列([

           应用程序。globalPut ( self. Variables . asa_price , Btoi ( sell_price )) ,

           应用程序。globalPut ( self.Variables.app_state , self.AppState.selling_in_progress ) , _ _ _ _ _

返回( Int ( 1 ))

])

返回If ( can_sell ) 。然后(更新状态)。否则(返回(Int (0 )))

该应用程序的“购买”功能是最难使用的。这部分代码由应用程序调用事务执行,该事务被组合成具有三个事务的原子传输:

  1. 应用程序调用事务执行包含在“购买”函数中的 PyTeal 代码。在那里,我们验证应用程序是否处于“AppState. sell_in _progress”状态,“asa_owner”接收“asa_price”算法,而“asa_buyer”接收 NFT。

  2. 向 NFT 供应商支付正确数量的算法的支付交易。

  3. NFT 通过原子转移交易从当前所有者转移到新所有者。前两个原子转移交易的发送者现在是新的所有者。

def购买(自我):

       valid_number_of_transactions = 全球。group_size () == Int ( 3 )

       asa_is_on_sale = 应用程序。globalGet ( self.Variables.app_state ) == self . _ 应用状态。销售进度

       valid_payment_to_seller =和(

           GTXN [ 1 ] 。type_enum () == TxnType。付款,

           GTXN [ 1 ] 。接收器() == 应用程序。globalGet ( self.Variables.asa_owner ) , #正确的接收者

           GTXN [ 1 ] 。金额()==应用程序。globalGet ( self.Variables.asa_price ) , #正确的金额

           GTXN [ 1 ] 。发件人() == Gtxn [ 0 ] 。sender () , # 相等的前两笔交易的发送者,也就是买家

           GTXN [ 1 ] 。发件人() == Gtxn [ 2 ] 。asset_receiver () # NFT 的正确接收者

)

       valid_asa_transfer_from_escrow_to_buyer =和(

           GTXN [ 2 ] 。type_enum () == TxnType。资产转移,

           GTXN [ 2 ] 。发件人()==应用程序。globalGet ( self.Variables.escrow_address ) , _ _ _

           GTXN [ 2 ] 。xfer_asset () == 应用程序。globalGet (自我。变量。asa_id ),

           GTXN [ 2 ] 。asset_amount () ==整数( 1 )

)

       can_buy =和( valid_number_of_transactions,

                     asa_is_on_sale,

                     valid_payment_to_seller,

                     valid_asa_transfer_from_escrow_to_buyer )

       update_state =序列([

           应用程序。globalPut ( self. Variables . asa_owner , Gtxn [ 0 ] . sender ()) , # 更新 ASA 的所有者。

           应用程序。globalPut ( self.Variables.app_state , self.AppState.active ) , #更新应用状态_ _

返回( Int ( 1 ))

])

返回If ( can_buy ) 。然后(更新状态)。否则(返回(Int (0 )))

提出停止销售

我们希望添加取消销售订单的功能作为应用程序的最终功能。如果“asa_owner”想要停止出售 NFT,他们可以通过实现“stop_ sell_offer”方法的应用程序调用交易来实现。这是一个相当简单的函数,只有当应用程序的发送者是 NFT 所有者时,应用程序的内部状态才会从“AppState . sell_in_progress”更新为“AppState.active” 。

def stop_sell_offer (自我):

       valid_number_of_transactions = 全球。group_size () ==整数( 1 )

       有效调用者 = Txn。发件人()==应用程序。globalGet (自我。变量。asa_owner )

       app_is_initialized = 应用程序。globalGet (自我。变量。app_state )!=自我。应用状态。未初始化

       can_stop_sales =和( valid_number_of_transactions,

                              有效调用者,

                              app_is_initialized )

       update_state =序列([

           应用程序。globalPut ( self.Variables.app_state , self.AppState.active ) , _ _ _ _ _

返回( Int ( 1 ))

])

返回If ( can_stop_sales ) 。然后(更新状态)。否则(返回(Int (0 )))

第三步:实现无状态智能合约

如前所述,我们将采用无状态智能合约作为 NFT 的回拨地址。一旦评估了合约中的代码,我们就可以将 NFT 从一个账户转移到另一个账户。

由于有状态智能合约包含 NFTMarketplace 应用程序的大部分功能,因此托管合约必须满足以下要求:

  • 合约签署 AssetTransfer 交易,这是原子转移的一部分。将 NFT 从一个地址转移到另一个地址时,唯一的方法是使用应用程序的“购买”方法。

  • 我们需要仔细检查原子传输的第一个事务是否调用了正确的应用程序。在编译托管合约中的代码时,我们将来自有状态智能合约的 id 作为“app_id”传递。

  • 使用“asa_id”参数,我们检查是否传输了正确的 NFT。每个 NFT 的托管地址会有所不同。

def nft_escrow ( app_id: int, asa_id: int ) :

返回序列([

Assert ( Global. group_size () == Int ( 3 )) , # 三个事务的原子传输

Assert ( Gtxn [ 0 ] . application_id () == Int ( app_id )) , # 我们正在调用正确的应用程序

断言(Gtxn [ 1 ] .type_enum ()== TxnType.Payment ),

断言( Gtxn [ 2 ] .asset_amount ( ) == Int ( 1 )) ,

Assert ( Gtxn [ 2 ] . xfer_asset () == Int ( asa_id )) , # 我们正在转移正确的 NFT

断言( Gtxn [ 2 ] .fee ( ) < = Int ( 1000 )) ,

断言( Gtxn [ 2 ] .asset_close_to () == Global.zero_address ( )) ,

断言( Gtxn [ 2 ] .rekey_to () == Global.zero_address ( )) ,

返回( Int ( 1 ))

])

我们使用托管无状态智能合约完成了 NFTMarketplace 应用程序中的所有 PyTeal 代码。Algorand 区块链将用于运行此代码。我们现在唯一要做的就是将与合约的沟通付诸行动。

第四步:通讯服务

交易是我们与智能合约沟通的方式。将交易的创建分成不同的功能是一种聪明的方法。此外,我们将逻辑功能划分为不同的类,我们将其称为服务。

我们的应用程序中有两种类型的服务:

  • 与有状态智能合约的所有交互都是通过“NFTMarketplace”服务实现的。我们可以使用该服务来调用“NFTMarketplaceInterface”中实现的方法。此外,我们还有另一种将应用程序部署到区块链的方式。

  • “NFTMarketplace”中提供以下方法:

    我们不在应用程序的 UI 中使用“stop_sell_offer”方法;因此,我们没有将它包含在服务类中。实现必要的事务以执行该方法是一项可取的练习。

    • “应用程序初始化”

    • “初始化托管”

    • “fund_escrow”

    • “make_sell_offer”

    • “买_nft”

  • “NFTService”允许我们构建 NFT、修改其凭据并向其中添加用户。
    因此,“NFTService”由以下方法组成:

    • “创建_nft”

    • “change_nft_credentials”

    • “选择参加”

NFT 市场

每个“NFTMarketplace”服务实例都将代表一个单独的有状态智能合约,该合约已被放置在网络上。这些合约中的每一个都负责监督单个 NFT 的状态。

以下代码用于设置智能合约:

NFTMarketplace类:

def __init__ ( self, admin_pk, admin_address, nft_id, client ) :

       自己。admin_pk = admin_pk

       自己。admin_address = admin_address

       自己。nft_id = nft_id

       自己。客户=客户

       自己。青色版本= 4

       自己。nft_marketplace_asc1 = NFTMarketplaceASC1 ()

       自己。app_id = 无

除了适当的参数外,我们还在类的构造方法中初始化“NFTMarketplaceASC1”有状态智能合约。提交给网络的TEAL码将从该物品中获取。

我们定义的第一个函数生成并执行提交有状态智能合约的网络交易。

我们可以通过以下代码获得它:

def app_initialization (自我,nft_owner_address ):

       批准程序编译 = compileTeal (

           自己。nft_marketplace_asc1 。批准程序(),

           模式=模式。应用,

           版本= 4 ,

)

       clear_program_compiled = compileTeal (

           自己。nft_marketplace_asc1 。clear_program () ,

           模式=模式。应用,

           版本= 4

)

       批准程序字节 = 网络交互。编译程序(

           客户=自己。客户端,source_code=approval_program_compiled

)

       clear_program_bytes = 网络交互。编译程序(

           客户=自己。客户端,source_code=clear_program_compiled

)

       app_args = [

decode_address ( nft_owner_address ) ,

decode_address ( self.admin_address ) , _

]

       app_transaction = ApplicationTransactionRepository。创建应用程序(

           客户=自己。客户,

           creator_private_key=自己。admin_pk ,

           批准程序=批准程序字节,

           clear_program=clear_program_bytes,

           全局模式=自我。nft_marketplace_asc1 。全局模式,

           local_schema=self。nft_marketplace_asc1 。local_schema ,

           app_args=app_args,

           外国资产= [自我。nft_id ] ,

)

       tx_id = 网络交互。提交交易(

           自己。客户端,事务=app_transaction

)

       交易响应=自我。客户端。pending_transaction_info ( tx_id )

       自己。app_id = transaction_response [ “应用程序索引” ]

返回tx_id

上述函数的目标是定义一个应用程序创建事务并将其提交到网络。该事务可以接受各种参数,因此我们需要指定我们将在应用程序中使用的参数。“NFTMarketplaceASC1”合约的“app_initialization”方法定义了对具体参数的需求。

以下阶段总结了实现逻辑:

  • 从有状态的智能合约中,我们获取并编译明确和批准程序。

  • 生成一个存储“nft_owner_address”和“admin_address”的“app_args”数组。当应用程序创建事务时,这个数组将被发送到“apps_args”。

  • 在应用程序中传输“nft_id”以创建交易的 foreign_assets 字段参数。

如果此交易成功完成,我们已成功部署应用程序来管理具有特定“nft_id”的 NFT 的销售和转售。

“ nft_id”和“app_id”是初始化托管地址的必要参数,现在可用。我们稍后会使用这个地址作为 NFT 中的回拨地址。

我们可以使用“nft_escrow”函数获取托管地址和托管字节:

   @财产

默认托管字节(自我):

如果自我。app_id为无:

           raise ValueError ( "App 未部署" )

       escrow_fund_program_compiled = compileTeal (

nft_escrow ( app_id= self.app_id , asa_id= self.nft_id ) ,

           模式=模式。签名,

           版本= 4 ,

)

返回网络交互。编译程序(

           客户=自己。客户端,source_code=escrow_fund_program_compiled

)

   @财产

def escrow_address ( self ) :

返回算法逻辑。地址(self.escrow_bytes )_

我们现在需要执行“initialize_escrow”函数来实现相应的交易,进而在有状态的智能合约中设置托管地址。请记住,在与此功能交互之前,我们必须修改 NFT 的管理凭据。在“NFTService”中,将对修改NFT管理的代码进行说明。

定义初始化托管(自我):

       app_args = [

           自己。nft_marketplace_asc1 。应用方法。初始化托管,

decode_address ( self. escrow_address ) ,

]

       initialize_escrow_txn = ApplicationTransactionRepository。调用应用程序(

           客户=自己。客户,

           caller_private_key=self。admin_pk ,

           app_id=自己。app_id ,

           on_complete=algo_txn。完成。NoOpOC ,

           app_args=app_args,

           外国资产= [自我。nft_id ] ,

)

       tx_id = 网络交互。提交交易(

           自己。客户端,事务=initialize_escrow_txn

)

返回tx_id

成功提交“initialize_escrow”交易后,有状态智能合约的起始状态更新为“AppState.active” 。我们必须执行“make_sell_offer”和“buy_nft”方法。

“ make_sell_offer”只是一个普通的应用程序调用事务,我们传递两个参数:方法名称和卖出报价。当交易发送者拥有必要的 NFT 时,有状态的智能合约将确认交易。

def make_sell_offer ( self, sell_price: int, nft_owner_pk ) :

       app_args = [自我。nft_marketplace_asc1 。应用方法。make_sell_offer , sell_price ]

       app_call_txn = ApplicationTransactionRepository。调用应用程序(

           客户=自己。客户,

           caller_private_key=nft_owner_pk,

           app_id=自己。app_id ,

           on_complete=algo_txn。完成。NoOpOC ,

           app_args=app_args,

           sign_transaction=真,

)

       tx_id = 网络交互。submit_transaction ( self.client , transaction= app_call_txn )

返回tx_id

按照惯例,我们必须执行最复杂的方法。要购买 NFT,我们必须提交三个原子转移交易:

  1. 买方对应用程序调用进行的应用程序调用交易。我们只将方法名作为应用参数发送,比较简单。

  2. 买方向 NFT 的卖方进行支付交易。此交易的价值应与销售要约中指定的金额相同。

  3. 从托管地址到购买者地址的原子转移交易。托管地址也是 NFT 的回拨地址,NFT 可以从一个地址转移到另一个地址。此交易必须使用逻辑签名进行签名。一旦托管合约中的 TEAL 逻辑被评估为 true,则交易被批准。

生成购买 NFT 所需的所有交易的“buy_nft”函数在下面的代码中进行了描述。

def buy_nft (自我,nft_owner_address,buyer_address,buyer_pk,buy_price ):

# 1. 应用调用txn

       app_args = [

           自己。nft_marketplace_asc1 。应用方法。买

]

       app_call_txn = ApplicationTransactionRepository。call_application ( client = self.client ,

                                                                        caller_private_key=buyer_pk,

                                                                        app_id=自己。app_id ,

                                                                        on_complete=algo_txn。完成。NoOpOC ,

                                                                        app_args=app_args,

                                                                        sign_transaction=假)

# 2. 支付交易:买家->卖家

       asa_buy_payment_txn = PaymentTransactionRepository。付款(客户=自我。客户,

                                                                  发件人地址=买家地址,

                                                                  接收者地址=nft_owner_address,

                                                                  金额=购买价格,

                                                                  sender_private_key=无,

                                                                  sign_transaction=假)

# 3. 资产转移交易:托管 -> 买方

       asa_transfer_txn = ASATransactionRepository。asa_transfer (客户=自我。客户,

                                                                发件人地址=自己。托管地址,

                                                                接收者地址=买家地址,

                                                                数量= 1 ,

                                                                asa_id=自己。nft_id ,

                                                                撤销目标=nft_owner_address,

                                                                sender_private_key=无,

                                                                sign_transaction=假)

# 原子传输

       gid = algo_txn。calculate_group_id ([ app_call_txn,

                                          asa_buy_payment_txn,

                                          asa_transfer_txn ])

       app_call_txn。组= gid

       asa_buy_payment_txn。组= gid

       asa_transfer_txn。组= gid

       app_call_txn_signed = app_call_txn。签名( buyer_pk )

       asa_buy_txn_signed = asa_buy_payment_txn。签名( buyer_pk )

       asa_transfer_txn_logic_signature = algo_txn。LogicSig ( self.escrow_bytes ) _

       asa_transfer_txn_signed = algo_txn。LogicSigTransaction ( asa_transfer_txn, asa_transfer_txn_logic_signature )

       签名组 = [ app_call_txn_signed,

                       asa_buy_txn_signed,

                       asa_transfer_txn_signed ]

       tx_id = 自我。客户端。发送交易(签名组)

返回tx_id

执行此方法后,“NFTMarketplace”服务现已完成。

NFT服务

“NFTService”类的每个实例将负责区块链上的单个 NFT。生成 NFT 的必要参数,例如创建者的地址、NFT 名称和包含 ipfs 图像的可选 URL,需要发送到初始化程序。

NFTService类:

def __init__ (

           自己,

           nft_creator_address: str,

           nft_creator_pk:str,

           客户,

           单位名称:str,

           资产名称:str,

           nft_url=无,

) :

       自己。nft_creator_address = nft_creator_address

       自己。nft_creator_pk = nft_creator_pk

       自己。客户=客户

       自己。单位名称= 单位名称

       自己。资产名称= 资产名称

       自己。nft_url = nft_url

       自己。nft_id = 无

资产配置交易用于生成 NFT。NFT 的每个管理字段此时都已填充,我们稍后可以更改。如果我们用这些管理凭证离开 NFT,有状态的智能合约应该将其关闭。

def create_nft (自我):

       signed_txn = ASATransactionRepository。create_non_fungible_asa (

           客户=自己。客户,

           creator_private_key=自己。nft_creator_pk ,

           单位名称=自我。单位名称,

           资产名称=自己。资产名称,

           注意=无,

           经理地址=自己。nft_creator_address ,

           保留地址=自己。nft_creator_address ,

           冻结地址=自己。nft_creator_address ,

           回拨地址=自己。nft_creator_address ,

           网址=自我。nft_url ,

           default_frozen=真,

           sign_transaction=真,

)

       nft_id, tx_id = 网络交互。submit_asa_creation (

           客户=自己。客户端,事务=已签名_txn

)

       自己。nft_id = nft_id

返回tx_id

实现了“change_nft_credentials_txn”方法,该方法清除了除托管地址之外的所有 NFT 凭证。

def change_nft_credentials_txn ( self, escrow_address ) :

       txn = ASATransactionRepository。change_asa_management (

           客户=自己。客户,

           current_manager_pk=自己。nft_creator_pk ,

           asa_id=自己。nft_id ,

           经理地址= “” ,

           保留地址= “” ,

           冻结地址= “” ,

           strict_empty_address_check=假,

           clawback_address=escrow_address,

           sign_transaction=真,

)

       tx_id = 网络交互。submit_transaction ( self.client , transaction= txn )

返回tx_id

最后,我们必须执行一种简单的方法,允许用户选择特定的 NFT。这是 Algorand 网络的一项重要特性,它可以防止用户接收未经授权存储在其钱包中的代币。成功选择后,用户可以获得 Algorand 标准资产。

def opt_in ( self, account_pk ) :

       opt_in_txn = ASATransactionRepository。asa_opt_in (

           客户=自己。客户端,sender_private_key=account_pk,asa_id=self。nft_id

)

       tx_id = 网络交互。submit_transaction ( self.client , transaction= opt_in_txn )

返回tx_id

第 5 步:部署 Algorand 测试网

最后,我们已经执行了一切。多亏了这些服务,我们现在可以在 Algorand 测试网上轻松部署和测试 NFTMarketplace 应用程序。下面的脚本复制了销售报价并由特定买家执行。从下面的代码中,我们可以看到一切都抽象得很好,使得事务执行变得方便。

nft_service。创建_nft ()

nft_marketplace_service。app_initialization ( nft_owner_address=admin_addr )

nft_service。change_nft_credentials_txn ( escrow_address= nft_marketplace_service.escrow_address )

nft_marketplace_service。初始化托管()

nft_marketplace_service。基金托管()

nft_marketplace_service。make_sell_offer ( sell_price= 100000 , nft_owner_pk=admin_pk )

nft_service。opt_in ( buyer_pk )

nft_marketplace_service。buy_nft ( nft_owner_address=admin_addr,

                               买家地址=买家地址,

                               买家pk=买家pk,

                               购买价格= 100000 )

结论

不可替代代币日益流行,现有 NFT 市场(如 Axie Infinity、Rarible 和 OpenSea)的流量也在增加。大公司发现这一新的技术浪潮是一个有利可图的机会,可以投资并利用该机会实现业务增长,充分利用其潜力。随着巨大的业务增长可能性,对由强大的区块链生态系统驱动的 NFT 市场的需求出现了。

尽管有许多区块链平台可用,但 Algorand 是 NFT 市场开发最好和最可靠的平台之一。它的推出是为了解决同时实现可扩展性、安全性和去中心化的区块链三难困境。作为最快的网络之一,它可以在不到五秒的时间内完成交易,也是一种具有成本效益的协议。其独特的 Pure Proof-of-Stake 共识机制、强大的安全性、有保证的最终性、全球范围的覆盖范围、广泛的去中心化和低交易成本使其成为开发和部署标准 NFT 市场的最佳平台之一。



推荐阅读
天品互联

NFT数字藏品-元宇宙系统开发-北京天品互联,免费24小时报价,可以定制开发NFT数字藏品交易平台、NFT头像、概念、IBOX、hotdog数字艺术品等软件开发定制,提供元宇宙社交交友、电商、虚拟人物主播、游戏、3D展会虚拟会议方面的元宇宙系统制作,包括VR头显设备系统、APP、小程序、web3.0系统开发。

微信咨询

扫描微信二维码
同市场经理沟通需求

感受专业服务,从来电咨询开始
153-212-50321