当前位置: 首页 > article >正文

【p2p、分布式,区块链笔记 Blockchain】truffle002 unleashed_rentable_nft 项目

  • 上一篇:【p2p、分布式,区块链笔记 Blockchain】truffle001 以太坊开发框架truffle初步实践

项目结构

  • 项目实现了一个简单的可租赁的 NFT 系统,用户可以铸造和销毁 NFT。这是作者写的项目介绍(后边看issue才发现的),建议直接看这篇。
    在这里插入图片描述

合约:RentablePets.sol

  • mint 函数:允许用户创建新的 NFT,并为其设置唯一的 token ID 和元数据 URI。
mint - 百度翻译
英[mɪnt][mɪnt]

n. 薄荷;造币厂;薄荷糖;铸币厂;大量的钱;
vt. ();铸造(硬币);
adj. 完美的;新造的;
  • burn 函数:允许用户销毁指定 ID 的 NFT,删除该 NFT 及其相关数据。
solidity
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

import "./ERC4907.sol"; // RentablePets.sol <= ERC4907.sol <= IERC4907.sol
                        // 导入自定义的 ERC4907 合约,ERC4907 是 ERC721 的扩展标准,支持租赁功能。

import "@openzeppelin/contracts/utils/Counters.sol"; // 导入 OpenZeppelin 的 Counters 库,管理可自动递增的计数器,用于生成唯一的 token ID。

contract RentablePets is ERC4907 { // 定义一个名为 RentablePets 的合约,继承自 ERC4907

  using Counters for Counters.Counter;  // Use the Counters library for the Counters.Counter type

  Counters.Counter private _tokenIds;  // 定义一个私有的 `_tokenIds` 计数器,跟踪和递增每次铸造的新 NFT 的唯一标识符(token ID)。

  constructor() ERC4907("RentablePets", "RP") {}  // 构造函数,在合约部署时调用,初始化 ERC4907 标准的 NFT 名称为 "RentablePets",符号为 "RP"。

  function mint(string memory _tokenURI) public {  // 定义一个 `mint` 函数,允许公开调用,用户可以通过此函数铸造新的 NFT。

    _tokenIds.increment(); // 每次铸造 NFT 时,计数器 `_tokenIds` 自增,以确保每个 NFT 都有一个唯一的 token ID。
    uint256 newTokenId = _tokenIds.current();  // 获取当前的计数器值(即新 NFT 的唯一 token ID)。
    
    _safeMint(msg.sender, newTokenId); // 安全铸造新 NFT,将其分配给调用者 `msg.sender`,确保目标地址能够接收 ERC721 代币。
    _setTokenURI(newTokenId, _tokenURI); // 为新铸造的 NFT 设置其元数据 URI,通常指向存储在链外的资源(如图片或描述)的 URL。
  }

  function burn(uint256 tokenId) public {  // 定义一个 `burn` 函数,允许公开调用,用户可以通过此函数销毁指定 ID 的 NFT。
    _burn(tokenId); // 调用 `_burn` 函数销毁对应的 token ID,永久移除该 NFT 及其元数据。
  }
}
  1. ERC4907 和 Counters 导入:引入了自定义的 ERC4907 标准(可租赁的 NFT 标准)和 OpenZeppelin 的计数器工具,用于自动生成唯一的 token ID。
  2. 合约定义:合约 RentablePets 继承了 ERC4907 的所有功能(包括 ERC721 标准和租赁扩展)。
  3. 构造函数:初始化合约时,设定 NFT 名称为 “RentablePets”,符号为 “RP”。
  • 编译器版本:
solc: {
      version: ">=0.4.22 <0.9.0"
      }
  • 开发依赖:
{
  "dependencies": {
    "@openzeppelin/contracts": "^4.8.0",
    "@truffle/hdwallet-provider": "^1.7.0"
  },
  "devDependencies": {
    "@openzeppelin/test-helpers": "^0.5.15"
  }
}

迁移部署:migrations/1_deploy_contracts.js

migrations
英[/maɪˈgreɪʃənz/][/maɪˈgreɪʃənz/]
n.(程序或硬件的)迁移,转移;迁移;迁徙;移居;(计算机系统的)改变
migration的复数
// artifacts 是由 Truffle 提供的一个全局对象,允许我们引入编译后的智能合约文件。
// 它将编译器生成的 ABI(Application Binary Interface,应用二进制接口)和字节码与 JavaScript 代码连接起来。
const RentablePets = artifacts.require("RentablePets"); // 引入名为 RentablePets 的智能合约。Truffle 会寻找一个名为 RentablePets 的合约,并将其映射到 JavaScript 对象中供后续部署时使用。

// 当运行 truffle migrate 或 truffle deploy 时,Truffle 会自动执行这个文件,并按照这里定义的步骤来部署合约。
module.exports = function (deployer) {
  deployer.deploy(RentablePets);// 部署一个智能合约到区块链上
};

运行脚本:scripts/mint.js

var RentablePets = artifacts.require("RentablePets");

const main = async (cb) => {
    try {
        const argv = require('yargs/yargs')(process.argv.slice(4))
            .default("from", (await web3.eth.getAccounts())[0])
            .argv; // 使用yargs库进行参数解析
        const rentablePets = await RentablePets.deployed()
        let txn = await rentablePets.mint("fakeURI", {from: argv.from}) // 调用 RentablePets 合约的 mint 方法,传入一个字符串 "fakeURI" 作为 NFT 的 URI,
                                                                        // 并指定 from 参数作为发送交易的账户。
                                                                        // 这个调用将返回一个交易对象(txn),该对象包含关于交易的信息,例如交易哈希、区块号等。
        console.log(txn);
    } catch(err) {
        console.log(err);
    }
    cb(); // cb 是一个回调函数,用于在脚本执行完成后通知 Truffle 该任务已经结束
  }
  
module.exports = main;
// truffle exec scripts/mint.js --from <你的账户地址>
  • 编译与部署
➜  workspace git:(main) ✗ truffle compile --all


Compiling your contracts...
===========================
✓ Fetching solc version list from solc-bin. Attempt #1
✓ Downloading compiler. Attempt #1.
> Compiling ./contracts/ERC4907.sol
> Compiling ./contracts/IERC4907.sol
> Compiling ./contracts/RentablePets.sol
> Compiling @openzeppelin/contracts/token/ERC721/ERC721.sol
> Compiling @openzeppelin/contracts/token/ERC721/IERC721.sol
> Compiling @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
> Compiling @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol
> Compiling @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol
> Compiling @openzeppelin/contracts/utils/Address.sol
> Compiling @openzeppelin/contracts/utils/Context.sol
> Compiling @openzeppelin/contracts/utils/Counters.sol
> Compiling @openzeppelin/contracts/utils/Strings.sol
> Compiling @openzeppelin/contracts/utils/introspection/ERC165.sol
> Compiling @openzeppelin/contracts/utils/introspection/IERC165.sol
> Compiling @openzeppelin/contracts/utils/math/Math.sol
> Artifacts written to /project/workspace/build/contracts
> Compiled successfully using:
   - solc: 0.8.15+commit.e14f2714.Emscripten.clang
➜  workspace git:(main) ✗ truffle migrate


Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.


Starting migrations...
======================
> Network name:    'development'
> Network id:      1729358815666
> Block gas limit: 6721975 (0x6691b7)


1_deploy_contracts.js
=====================

   Deploying 'RentablePets'
   ------------------------
   > transaction hash:    0xe175c15f56056f7234713dd721c5761d5e5316f8598db9ac030d067b0bd61d2c
   > Blocks: 0            Seconds: 0
   > contract address:    0x4cd45fa514493686dC9ebd9B82F2b484C4A04791
   > block number:        1
   > block timestamp:     1729359105
   > account:             0xE80E1ab42c8daD385cff236eA11495C719529617
   > balance:             99.93983968
   > gas used:            3008016 (0x2de610)
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.06016032 ETH

   > Saving artifacts
   -------------------------------------
   > Total cost:          0.06016032 ETH

Summary
=======
> Total deployments:   1
> Final cost:          0.06016032 ETH

交互

➜  workspace git:(main) ✗ truffle console

truffle(development)> const Web3 = require('web3');
undefined
truffle(development)> const web3 = new Web3('http://127.0.0.1:8545');
undefined
truffle(development)> const v = web3.eth.getAccounts();
undefined
truffle(development)> console.log(v)
Promise {
  [
    '0xE80E1ab42c8daD385cff236eA11495C719529617',
    '0x5370ab73FCe6E6379065b1bcc28ca2AADf25CcC3',
    '0x5e70aa3FF93611F24779eA6d061af288d9E76d29',
    '0x78492007d7Fd3c2E367C940c69fB74314ddDa736',
    '0x25106c3591c2e3bB48A0D68e3d1252bb4Aa90CDE',
    '0x79B45863062ae0216143369De21442F92A1176b7',
    '0x4A31abd39EC9ce5F1471ffA6e48a9c65B70D6Da7',
    '0xf041c963841d797065dB5AeF0D6D146D7E3f2Fb0',
    '0x420D956ad2407533A0cD140d53B826E8D4B1BB95',
    '0x87AcFD4c4E02bD337978AB089dF24F83eceB5f4d'
  ],
  [Symbol(async_id_symbol)]: 448,
  [Symbol(trigger_async_id_symbol)]: 8
}
undefined
truffle(development)> const rentablePets = await RentablePets.deployed()
undefined
truffle(development)> let txn = await rentablePets.mint("fakeURI", {from: '0xE80E1ab42c8daD385cff236eA11495C719529617'})
undefined
truffle(development)>  console.log(txn);
{
  tx: '0x719254cfa3be55c078e2800a820a04d338862c69a627df16e4d63df4871613b4',
  receipt: {
    transactionHash: '0x719254cfa3be55c078e2800a820a04d338862c69a627df16e4d63df4871613b4',
    transactionIndex: 0,
    blockHash: '0xa91f80b69644dd3bb8b7d96783230a9163ebfa851cd1ca8ce67434f9811c1147',
    blockNumber: 2,
    from: '0xe80e1ab42c8dad385cff236ea11495c719529617',
    to: '0x4cd45fa514493686dc9ebd9b82f2b484c4a04791',
    gasUsed: 114934,
    cumulativeGasUsed: 114934,
    contractAddress: null,
    logs: [ [Object] ],
    status: true,
    logsBloom: '0x00000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000008000000000000000000040000000000000000000000000000020000000000000000000800000000000000000000000010000000000000000000000000000000000400000000000001000000000000000000000000000004000000000000000000000000000080000000000000000000000000000000000002000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000',
    rawLogs: [ [Object] ]
  },
  logs: [
    {
      logIndex: 0,
      transactionIndex: 0,
      transactionHash: '0x719254cfa3be55c078e2800a820a04d338862c69a627df16e4d63df4871613b4',
      blockHash: '0xa91f80b69644dd3bb8b7d96783230a9163ebfa851cd1ca8ce67434f9811c1147',
      blockNumber: 2,
      address: '0x4cd45fa514493686dC9ebd9B82F2b484C4A04791',
      type: 'mined',
      removed: false,
      id: 'log_4e200077',
      event: 'Transfer',
      args: [Result]
    }
  ]
}
undefined
truffle(development)> 

Ganache输出

  workspace git:(main) ✗ ganache-cli                
Ganache CLI v6.12.2 (ganache-core: 2.13.2)

Available Accounts
==================
(0) 0xE80E1ab42c8daD385cff236eA11495C719529617 (100 ETH)
(1) 0x5370ab73FCe6E6379065b1bcc28ca2AADf25CcC3 (100 ETH)
(2) 0x5e70aa3FF93611F24779eA6d061af288d9E76d29 (100 ETH)
(3) 0x78492007d7Fd3c2E367C940c69fB74314ddDa736 (100 ETH)
(4) 0x25106c3591c2e3bB48A0D68e3d1252bb4Aa90CDE (100 ETH)
(5) 0x79B45863062ae0216143369De21442F92A1176b7 (100 ETH)
(6) 0x4A31abd39EC9ce5F1471ffA6e48a9c65B70D6Da7 (100 ETH)
(7) 0xf041c963841d797065dB5AeF0D6D146D7E3f2Fb0 (100 ETH)
(8) 0x420D956ad2407533A0cD140d53B826E8D4B1BB95 (100 ETH)
(9) 0x87AcFD4c4E02bD337978AB089dF24F83eceB5f4d (100 ETH)

Private Keys
==================
(0) 0xe398d80025ef59f3d1bc31bd55eac87ed2ba30e267a2b1de2f7a2d9bbe1ef573
(1) 0xefff1fb2953c1808bbc184a502139efc462f6edcd379a98135f3a01999ec721d
(2) 0xee46e7e7b3f38de97dfdd4b01f6c17866787a9c9b1372c452c04813a2755c1c5
(3) 0xb1ff4eacd6a96aadb020cac360eed51fb29acf7ed3d097dd307f4a6b5f655f2d
(4) 0x13a1679fb9420333f814506d384c7bef6a6c923353f389016c5944e5da068998
(5) 0xfa5f628ac0835d57b433c8278d1fe0d3f7c7f8fbaea74711f8b4decd671f09ec
(6) 0xd3acdd34343ab8c455fbe3734449dc50fedeb7973de090766a99e0836fa46b1c
(7) 0x5d20c3b08b8c51a50022d4ec5eb84531b06c71ec805de6aebf1b0b7c42c02154
(8) 0x9b9920b4b9d3d07dd0069438dc040b95d42ec29e38bee10d63095aff356eb018
(9) 0xcfa72ab66dbc451b803828eda8c6a2ce86925af8f98f8b0c97b6964e6885daf7

HD Wallet
==================
Mnemonic:      shop rule advance release dumb unveil pretty where search attract name exclude
Base HD Path:  m/44'/60'/0'/0/{account_index}

Gas Price
==================
20000000000

Gas Limit
==================
6721975

Call Gas Limit
==================
9007199254740991

Listening on 127.0.0.1:8545
eth_blockNumber
net_version
eth_accounts
eth_getBlockByNumber
eth_accounts
net_version
eth_getBlockByNumber
eth_getBlockByNumber
net_version
eth_getBlockByNumber
eth_estimateGas
net_version
eth_blockNumber
eth_getBlockByNumber
eth_estimateGas
eth_getBlockByNumber
eth_gasPrice
eth_sendTransaction

  Transaction: 0xe175c15f56056f7234713dd721c5761d5e5316f8598db9ac030d067b0bd61d2c
  Contract created: 0x4cd45fa514493686dc9ebd9b82f2b484c4a04791
  Gas usage: 3008016
  Block Number: 1
  Block Time: Sat Oct 19 2024 17:31:45 GMT+0000 (Coordinated Universal Time)

eth_getTransactionReceipt
eth_getCode
eth_getTransactionByHash
eth_getBlockByNumber
eth_getBalance
eth_blockNumber
net_version
eth_accounts
eth_accounts
eth_blockNumber
net_version
eth_accounts
eth_accounts
eth_accounts
eth_getBlockByNumber
eth_getBlockByNumber
eth_estimateGas
eth_getBlockByNumber
eth_gasPrice
eth_sendTransaction

  Transaction: 0x719254cfa3be55c078e2800a820a04d338862c69a627df16e4d63df4871613b4
  Gas usage: 114934
  Block Number: 2
  Block Time: Sat Oct 19 2024 17:40:55 GMT+0000 (Coordinated Universal Time)

eth_getTransactionReceipt

eth_getBlockByNumber
eth_getBlockByNumber
eth_getBlockByNumber
eth_getBlockByNumber
eth_getBlockByNumber
eth_getBlockByNumber

http://www.kler.cn/news/362838.html

相关文章:

  • GEE数据集:1984-2022 年间加拿大 6.5 亿公顷森林生态系统的年度优势树种(也称主要树种)地图
  • Windows 操作系统中事件驱动架构与注册表
  • ecmp观察
  • 基于YOLO的钢材缺陷检测系统设计与实现
  • Ubuntu 2张4090,显卡安装,无法双屏显示
  • 【iOS】AFNetworing初步学习
  • 深入理解 IP 协议
  • 大物 真空中的静电场
  • 微前端之模块联邦架构
  • Linux 中 .bash_history、.bash_logout 等用户配置文件
  • Linux杀毒-KVRT
  • 黑马javaWeb笔记重点备份12:yml格式配置文件
  • visual studio设置修改文件字符集方法
  • MyBatis入门之一对多关联关系(示例)
  • 【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【DSP指令加速篇】
  • 【在Linux世界中追寻伟大的One Piece】Socket编程UDP
  • 智慧旅游平台开发微信小程序ssm+论文源码调试讲解
  • Java 开发——(上篇)从零开始搭建后端基础项目 Spring Boot 3 + MybatisPlus
  • Qt开发-----线程调度
  • Python异常检测- 单类支持向量机(One-Class SVM)
  • Could not find artifact cn.hutool:hutool-all:jar:8.1 in central 导入Hutool报错
  • 鸿蒙HarmonyOS NEXT 5.0开发(2)—— ArkUI布局组件
  • 【推导过程】常用连续分布的数学期望、方差、特征函数
  • 031_基于nodejs的旅游推荐网站
  • Vue 的虚拟 DOM
  • 策略模式是一种行为设计模式