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

server/2024/10/21 9:13:05/

项目结构

  • 项目实现了一个简单的可租赁的 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 的合约,继承自 ERC4907using Counters for Counters.Counter;  // Use the Counters library for the Counters.Counter typeCounters.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 --allCompiling 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 migrateCompiling 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 ETHSummary
=======
> Total deployments:   1
> Final cost:          0.06016032 ETH

交互

➜  workspace git:(main) ✗ truffle consoletruffle(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) 0xcfa72ab66dbc451b803828eda8c6a2ce86925af8f98f8b0c97b6964e6885daf7HD 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
==================
20000000000Gas Limit
==================
6721975Call Gas Limit
==================
9007199254740991Listening 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_sendTransactionTransaction: 0xe175c15f56056f7234713dd721c5761d5e5316f8598db9ac030d067b0bd61d2cContract created: 0x4cd45fa514493686dc9ebd9b82f2b484c4a04791Gas usage: 3008016Block Number: 1Block 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_sendTransactionTransaction: 0x719254cfa3be55c078e2800a820a04d338862c69a627df16e4d63df4871613b4Gas usage: 114934Block Number: 2Block Time: Sat Oct 19 2024 17:40:55 GMT+0000 (Coordinated Universal Time)eth_getTransactionReceipteth_getBlockByNumber
eth_getBlockByNumber
eth_getBlockByNumber
eth_getBlockByNumber
eth_getBlockByNumber
eth_getBlockByNumber

http://www.ppmy.cn/server/133595.html

相关文章

Linux常用命令详细解析(含完整命令演示过程)

目录 1. 目录结构介绍 2. Linux命令基础 2.1 命令和命令行 2.2 格式 3. 常用命令 3.1 产看目录命令——ls 3.2 通配符 3.3 改变工作目录命令——cd 3.4 查看当前路径命令——pwd 3.5 创建新的目录命令——mkdir 3.6 创建文件目录命令——touch 3.7 查看…

Android 原生程序使用gdb, addr2line, readelf调试

Platform: RK3368 OS: Android 6.0 Kernel: 3.10.0 文章目录 一 gdb1. 原生程序添加调试符号2. 主机上adb push 编译好的原生程序到设备3. 设备上使用gdbserver运行原生程序4. 主机上设置adb端口转发5. 主机上运行gdb调试 二 addr2line三 readelf 一 gdb GDB&#xff08;GNU…

云计算-----单机LNMP结构WordPress网站

LNMP结构 博客网站 day1 小伙伴们&#xff0c;LNMP结构在第一二阶段浅浅的学习过&#xff0c;这里我们可以离线部署该结构。L指&#xff08;虚拟机&#xff09;服务器&#xff0c;nginx&#xff08;前端代理服务器&#xff09;mysql数据库&#xff0c;最后基于php建设动态…

Windows10去掉隐藏文件仍找不到hosts文件的解决办法

正常情况下hosts文件在目录C:\Windows\System32\drivers\etc中&#xff0c;最近新装的Windows10系统发现该目录下没有hosts文件。 执行如下命令hosts文件出现&#xff1a; 执行 for /f %P in (dir %windir%\WinSxS\hosts /b /s) do copy %P %windir%\System32\drivers\etc &am…

【网络知识】LVS+KeepAlived实现负载均衡+高可用

目录 一、Linux Virtual Server (LVS)&#xff1a;构建高性能负载均衡器1. LVS 概述2. LVS 的工作原理3. LVS 的组件3.1 虚拟服务器 (Virtual Server)3.2 真实服务器 (Real Server)3.3 负载均衡器 (Load Balancer) 4. LVS 的配置和管理4.1 安装 IPVS 模块4.2 配置虚拟服务器4.3…

深入解析 Go 语言接口:多接口实现与接口组合的实际应用

文章目录 一、引言二、一个类型实现多个接口1. 定义多个接口2. 类型实现多个接口3. 使用多个接口 三、接口的组合1. 接口嵌套2. 实现复合接口 四、实际开发中的应用场景1. 多态与模块化设计2. 松耦合系统设计3. 测试与依赖注入4. 事件驱动架构中的应用 五、小结 一、引言 在 G…

如何分析 JVM 内存泄漏问题:常见原因、分析 JVM 内存泄漏的工具与步骤、如何避免 JVM 内存泄漏

文章目录 1. JVM 内存泄漏的常见原因2. 分析 JVM 内存泄漏的工具与步骤2.1 使用 jmap 工具生成堆转储文件2.2 使用 jvisualvm 分析堆转储2.3 使用 Eclipse Memory Analyzer Tool (MAT)2.4 监控 GC 日志2.5 实时监控内存使用情况 3. 如何避免 JVM 内存泄漏4. 总结5.相关博客 JVM…

vue.js【常用UI组件库】

Element Plus组件库 Element Plus是基于Vue 3开发的优秀的PC端开源UI组件库&#xff0c;它是Element的升级版&#xff0c;对于习惯使用Element的人员来说&#xff0c;在学习Element Plus时&#xff0c;不用花费太多的时间。因为Vue 3不再支持IE 11&#xff0c;所以Element Plu…