如何使用Alchemy开发NFT智能合约(ERC721)

🥸 本教程翻译自官网:[https://docs.alchemy.com/docs](https://docs.alchemy.com/docs)。对部分内容进行了修改。教程中所有实例经过本人实践,代码可见:https://github.com/ChuXiaoYi/web3Study 使用Solidity开发智能合约并在区块链上部署可能一开始听起来有些吓人:Solidity、安全性、gas优化、开发环境和gas费用,这些只是你需要了解的一些事情,才能让你的代码托管在区块链上。不用担心,我们来帮你梳理一下。 不过,幸运的是,在过去几个月中,已经发布了许多工具,让开发人员可以更轻松地进行智能合约开发工作。 像OpenZeppelin Wizard这样的工具,为开发人员提供了点击和编写功能,可以在短时间内创建可组合和安全的智能合约,再加上Web3开发人员工具Alchemy的支持,让编写和部署区块链上的代码的体验变得比以往任何时候都更容易、更快速、更可靠。 在本教程中,您将学习如何使用Alchemy、OpenZeppelin、Remix和Ethereum Goerli开发和部署ERC721(NFT)智能合约。 更具体地说,您将学习: - 如何使用OpenZeppelin和Remix编写和修改智能合约 - 使用[https://goerlifaucet.com/](https://goerlifaucet.com/)获取免费的Goerli ETH - 将其部署在Ethereum Goerli测试网络区块链上以节省gas费用 - 使用Filebase在IPFS上托管NFT令牌元数据。 - 铸造NFT并在OpenSea上可视化。 您也可以跟随视频教程: 让我们开始创建智能合约。 # 使用OpenZeppelin合约向导开发ERC721智能合约。 如前所述,在本教程中,您将使用OpenZeppelin向导创建智能合约,有两个主要原因: - 它是安全的。 - 它提供标准的智能合约。 当涉及编写智能合约时,安全性至关重要。有许多智能合约漏洞的例子,由于安全性不佳而导致恶意行为者窃取了数亿美元。 *你不想在部署到区块链上后有人窃取你所有宝贵的加密货币或NFT吧?* **OpenZeppelin服务于此目的**,是最大的智能合约标准维护者之一(ERC20、ERC721等),允许开发人员使用经过全面审核的代码来开发可靠的合约。 要开发我们的ERC721 NFT智能合约,您需要做的第一件事是[进入Open Zeppelin智能合约向导页面。](https://docs.openzeppelin.com/contracts/4.x/wizard) 进入页面后,您将看到以下编辑器: ![https://upload-images.jianshu.io/upload_images/6687907-5455a106d927aff6.png](https://upload-images.jianshu.io/upload_images/6687907-5455a106d927aff6.png) 点击左上角的ERC721按钮,选择要使用的ERC标准类型和要编写的合约类型: ![https://upload-images.jianshu.io/upload_images/6687907-2b85edec2ede92e1.png](https://upload-images.jianshu.io/upload_images/6687907-2b85edec2ede92e1.png) 现在您已经选择了合约标准,在左侧菜单中应该会看到一些选项: 让我们从选择代币的名称和符号开始。单击文本框中的“MyToken”,给它命名,然后用同样的方式设置符号,并将基础URI字段留空(代币名称将被OpenSea和Rarible用作集合名称)。 ![https://upload-images.jianshu.io/upload_images/6687907-ebebf1bf0581d082.png](https://upload-images.jianshu.io/upload_images/6687907-ebebf1bf0581d082.png) ## 选择NFT(ERC721)代币功能 现在您需要选择要集成到我们的智能合约中的功能,在“设置”部分之后,您将找到“功能”部分,在那里您将能够选择要包括在您的智能合约中的不同模块。 ![https://upload-images.jianshu.io/upload_images/6687907-c449e04a1db5f749.png](https://upload-images.jianshu.io/upload_images/6687907-c449e04a1db5f749.png) 在这种情况下,您将选择以下集成: - **Mintable**将创建一个仅特权账户可调用的铸造功能 - **Auto Increment IDs**将自动为您的NFT分配递增的ID - **Enumerable**将为您提供访问链上代币枚举和“totalSupply”等函数的功能,这些功能在默认的ERC721集成URI存储中不存在,以将元数据和图像与您的每个NFT相关联 - **URI Storage**以能够将URI与我们的NFT相关联 ![https://upload-images.jianshu.io/upload_images/6687907-2bd21b3b67bc5e89.png](https://upload-images.jianshu.io/upload_images/6687907-2bd21b3b67bc5e89.png) 为了本教程的目的,我们建议您不要勾选以下模块,以确保我们的NFT不受到任何类型的Tokenomic影响: - **可销毁的** - 用于销毁代币 - **可暂停的** - 用于暂停代币转移、销售等 - **投票** - 提供类似于代表和投票的治理功能 如果您想了解更多关于这些模块的信息,请查看[官方OpenZeppelin ERC721标准文档。](https://docs.openzeppelin.com/contracts/4.x/api/token/erc721) 现在,您已经选择了所需的功能,OpenZeppelin向导将填充智能合约的代码,它应该如下所示: ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract Alchemy is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable { constructor() ERC721("Alchemy", "ALC") {} function safeMint(address to, uint256 tokenId, string memory uri) public onlyOwner { _safeMint(to, tokenId); _setTokenURI(tokenId, uri); } // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId); } function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { super._burn(tokenId); } function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) { return super.tokenURI(tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } } ``` 是时候将我们的代码复制并带到 Remix IDE 上进行修改,并在区块链上部署它了。 ## 使用REMIX IDE修改和部署您的ERC721合约 现在您已经拥有了ERC721智能合约,让我们在Goerli Testnet上修改并部署它。为此,您将使用Remix IDE,这是一个专门为Solidity智能合约开发而设计的免费Web集成开发环境。 首先,正如您可能已经注意到的那样,在OpenZeppelin Wizard编辑器的顶部,有一个“在Remix中打开”的按钮: ![https://upload-images.jianshu.io/upload_images/6687907-14a7b27a99cb0fcb.png](https://upload-images.jianshu.io/upload_images/6687907-14a7b27a99cb0fcb.png) 点击它将在浏览器的新标签页中打开 REMIX IDE。 ### 使用Remix修改NFT智能合约 从合同的顶部开始,有一个“SPDX-License-Identifier”,它指定了您的代码将发布的许可证类型 - 在Web3应用程序中保持代码开源是一个好习惯,因为它将确保可信度。 ```solidity // SPDX-License-Identifier: MIT ``` 然后有 pragma - 编译器的版本,您将使用它来编译智能合约代码。小的 “^” 符号告诉编译器,0.8.0 到 0.8.9 之间的每个版本都适合编译我们的代码。 ```solidity pragma solidity ^0.8.4; ``` 然后我们导入一堆库并初始化智能合约。 ```solidity import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; ``` 然后我们初始化合约,继承我们从OpenZeppelin代码库中导入的所有标准: ```solidity contract Alchemy is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable {...} ``` 正如您所注意到的,`safeMint`函数具有“`onlyOwner`”修饰符 - 这将仅允许智能合约的所有者(部署智能合约的钱包地址)铸造NFT。您可能希望任何人都可以铸造NFT,为此,您需要从Mint函数中删除`onlyOwner`修饰符。 ```solidity function safeMint(address to, string memory uri) public { uint256 tokenId = _tokenIdCounter.current(); _tokenIdCounter.increment(); _safeMint(to, tokenId); _setTokenURI(tokenId, uri); } ``` 你也可以从合约声明 "Ownable" 和库导入中删除它 ```solidity import "@openzeppelin/contracts/access/Ownable.sol"; ``` 现在每个人都可以铸造我们的NFT,你需要避免其他人铸造的NFT数量超过我们收藏中的最大数量。为此,让我们指定可铸造的NFT的最大数量。 假设用户想要铸造总共10,000个NFT。为此,让我们创建一个新的uint256变量,称其为MAX_SUPPLY,并将其赋值为10,000。 ```solidity Counters.Counter private _tokenIdCounter; uint256 MAX_SUPPLY = 100000; constructor() ERC721("Alchemy", "ALCH") {} ``` 接下来,让我们进入`safeMint`函数并在第18行添加一个require语句: ```solidity require(_tokenIdCounter.current() <= MAX_SUPPLY, "I'm sorry we reached the cap"); ``` 让我们花点时间更好地了解Solidity中的“require”语句。 您可以在官方文档中阅读有关Solidity “require”语句的更多信息。 现在,您已经限制了NFT的最大供应量,是时候在Goerli测试网络上编译智能合约并部署它了。为此,您需要在[Alchemy.com](https://alchemy.com/?a=roadtoweb3weekone)上创建一个免费帐户,将其添加为Metamask的节点提供程序,并获取一些免费的Goerli ETH。 ## 创建免费的Alchemy帐户 首先,让我们导航到[alchemy.com](https://alchemy.com/?a=roadtoweb3weekone),单击“登录”并创建一个新帐户: ![https://upload-images.jianshu.io/upload_images/6687907-be3f5145e80fe7b3.png](https://upload-images.jianshu.io/upload_images/6687907-be3f5145e80fe7b3.png) 选择以太坊生态系统: ![https://upload-images.jianshu.io/upload_images/6687907-b9db691e61525226.png](https://upload-images.jianshu.io/upload_images/6687907-b9db691e61525226.png) 给您的应用程序和团队取一个名称,选择Goerli网络,然后点击创建应用程序: ![*Create App*](https://upload-images.jianshu.io/upload_images/6687907-ff0fd3190664a85c.png) *Create App* 完成流程后,我们将被重定向到仪表板页面。点击您选择的应用程序名称,“test”在这种情况下,**点击右上角的“查看密钥”按钮**,然后复制HTTP URL: ![*Your Application Details*](https://upload-images.jianshu.io/upload_images/6687907-d0e9234824a9e5a8.png) *Your Application Details* 接下来,您需要将Alchemy添加到Metamask作为Goerli RPC提供程序。如果您尚未安装Metamask,请确保按照此指南将其添加到您的浏览器并创建一个新钱包。 ## 将Alchemy Goerli添加到您的Metamask钱包 一旦安装Metamask,点击网络下拉菜单,然后点击“添加网络”! ![https://upload-images.jianshu.io/upload_images/6687907-abb451967b127ade.png](https://upload-images.jianshu.io/upload_images/6687907-abb451967b127ade.png) 您将被重定向到以下页面,在该页面上您需要填写Goerli网络和RPC URL信息。 ![*Fill in the Goerli Network and RPC Url*](https://upload-images.jianshu.io/upload_images/6687907-de19358cbad6835a.png) *Fill in the Goerli Network and RPC Url* 在表格中添加以下信息: - **Network name**:Alchemy Goerli - **New RPC URL:** Goerli Alchemy应用程序的HTTP URL - **Chain ID**:5 - **Currency Symbol**:GoerliETH - **Block Explorer:**[https://goerli.etherscan.io](https://goerli.etherscan.io/) 太棒了,你使用Alchemy将Goerli添加到了Metamask!🎉 现在是时候在Goerli上**部署我们的智能合约**了,但首先,你需要获得一些Goerli测试ETH。 ## 获取免费Goerli测试ETH 获取Goerli测试ETH非常简单,只需前往 [goerlifaucet.com](https://goerlifaucet.com/),将钱包地址复制到文本栏中,然后点击“发送ETH给我”: ![https://upload-images.jianshu.io/upload_images/6687907-b12658cc6ffff411.png](https://upload-images.jianshu.io/upload_images/6687907-b12658cc6ffff411.png) 在10-20秒后,您将在Metamask钱包中看到Goerli ETH。 您每24小时可以无需登录获得高达0.1 ETH,或者使用Alchemy账户可获得0.5 ETH。 现在您已经获得了测试ETH,**是时候在区块链上编译和部署我们的NFT智能合约了。** ## 在Goerli测试网络上编译和部署NFT智能合约 回到Remix,让我们点击页面左侧的编译器菜单,然后点击蓝色的“编译”按钮: ![https://upload-images.jianshu.io/upload_images/6687907-e2591a97b0116e03.png](https://upload-images.jianshu.io/upload_images/6687907-e2591a97b0116e03.png) 然后点击“部署和运行交易”菜单,点击环境下拉菜单,并选择“注入Web3”: **确保Metamask钱包在Alchemy Goerli网络上**,从合同下拉菜单中选择NFT智能合约,然后点击部署。 ![https://upload-images.jianshu.io/upload_images/6687907-8e5ef666e691da9e.png](https://upload-images.jianshu.io/upload_images/6687907-8e5ef666e691da9e.png) 一个 Metamask 弹出窗口将出现,点击 "sign",然后继续支付燃气费。 如果一切按预期工作,10 秒后你应该可以在 "已部署的合约" 下看到合约列表: ![https://upload-images.jianshu.io/upload_images/6687907-ff360d34bfcb10ce.png](https://upload-images.jianshu.io/upload_images/6687907-ff360d34bfcb10ce.png) 现在智能合约已经部署到Goerli测试网,是时候铸造我们的NFT了,但首先需要在IPFS上创建并上传元数据,让我们了解一下“元数据”这个术语的含义。 ## 什么是NFT元数据? ![https://upload-images.jianshu.io/upload_images/6687907-f02df853be7d0b89.png](https://upload-images.jianshu.io/upload_images/6687907-f02df853be7d0b89.png) 为了使OpenSea拉取ERC721代币的离线元数据,合约需要返回指向托管元数据的URI。为了找到这个URI,OpenSea、Rarible和其他流行的市场将使用ERC721Uristorage标准中包含的tokenURI方法。 ERC721中的tokenURI函数应返回HTTP或IPFS URL,例如ipfs://bafkreig4rdq3nvyg2yra5x363gdo4xtbcfjlhshw63we7vtlldyyvwagbq。当查询时,此URL应返回包含代币元数据的JSON blob数据。 您可以在官方OpenSea文档中阅读有关元数据标准的更多信息。 ## 如何格式化您的NFT元数据 根据OpenSea文档,NFT元数据应存储在.json文件中,并按以下结构进行组织: ```json { "description": "YOUR DESCRIPTION", "external_url": "YOUR URL", "image": "IMAGE URL", "name": "TITLE", "attributes": [ { "trait_type": "Base", "value": "Starfish" }, { "trait_type": "Eyes", "value": "Big" }, { "trait_type": "Mouth", "value": "Surprised" }, { "trait_type": "Level", "value": 5 }, { "trait_type": "Stamina", "value": 1.4 }, { "trait_type": "Personality", "value": "Sad" }, { "display_type": "boost_number", "trait_type": "Aqua Power", "value": 40 }, { "display_type": "boost_percentage", "trait_type": "Stamina Increase", "value": 10 }, { "display_type": "number", "trait_type": "Generation", "value": 2 }] } ``` 这里是每个属性存储的简要说明: | 属性 | 说明 | | --- | --- | | image | 该物品图片的 URL。可以是任何类型的图片(包括 SVG,OpenSea 会将其缓存为 PNG),可以是 IPFS URL 或路径。建议使用 350 x 350 的图片。 | | image_data | 如果您想要动态生成图片,则可以使用原始的 SVG 图片数据(不建议使用)。只有在不包含 image 参数时才使用此选项。 | | external_url | 该链接将出现在 OpenSea 网站上该资产图片下方,用户可以通过该链接离开 OpenSea,在您的网站上查看该资产。 | | description | 该物品的人类可读描述。支持 Markdown。 | | name | 该物品的名称。 | | attributes | 这些是该物品的属性,将出现在 OpenSea 网站上对该物品的页面上。(见下文) | | background_color | 该物品在 OpenSea 上的背景颜色。必须是六位数的十六进制码,不带前导符号。 | | animation_url | 一个指向该物品多媒体附件的 URL。支持的文件扩展名有 GLTF、GLB、WEBM、MP4、M4V、OGV、OGG 和仅音频的扩展名 MP3、WAV、OGA。animation_url 还支持 HTML 页面,允许我们使用 JavaScript 画布、WebGL 等构建丰富的体验和交互式 NFT。现在支持 HTML 页面内的脚本和相对路径。但是,不支持浏览器扩展访问。 | | youtube_url | 一个指向 YouTube 视频的 URL。 | 现在我们已经简要了解了令牌元数据中将包含什么内容,让我们学习如何创建它并将其存储在IPFS上。 ## 创建并上传IPFS上的元数据 首先,前往 `[filebase.com`](https://filebase.com/) 并创建一个新账户。 登录后,点击左侧菜单中的桶按钮,然后创建一个新桶: ![https://upload-images.jianshu.io/upload_images/6687907-2f0b78e7e7d21c69.png](https://upload-images.jianshu.io/upload_images/6687907-2f0b78e7e7d21c69.png) 进入存储桶,点击 **上传按钮**,上传你想用于 NFT 的图片,[我会使用以下图片](https://ipfs.filebase.io/ipfs/bafybeihyvhgbcov2nmvbnveunoodokme5eb42uekrqowxdennt2qyeculm)。 上传后,点击它并复制 IPFS 网关 URL: ![https://upload-images.jianshu.io/upload_images/6687907-b82d6e76423adbce.png](https://upload-images.jianshu.io/upload_images/6687907-b82d6e76423adbce.png) 使用任何文本编辑器,**粘贴以下JSON代码:** ```json { "description": "This NFT proves I've created and deployed my first ERC20 smart contract on Goerli with Alchemy Road to Web3", "external_url": "Alchemy.com/?a=roadtoweb3weekone", "image": "https://ipfs.filebase.io/ipfs/bafybeihyvhgbcov2nmvbnveunoodokme5eb42uekrqowxdennt2qyeculm", "name": "A cool NFT", "attributes": [ { "trait_type": "Base", "value": "Starfish" }, { "trait_type": "Eyes", "value": "Big" }, { "trait_type": "Mouth", "value": "Surprised" }, { "trait_type": "Level", "value": 5 }, { "trait_type": "Stamina", "value": 1.4 }, { "trait_type": "Personality", "value": "Sad" }, { "display_type": "boost_number", "trait_type": "Aqua Power", "value": 40 }, { "display_type": "boost_percentage", "trait_type": "Stamina Increase", "value": 10 }, { "display_type": "number", "trait_type": "Generation", "value": 2 }] } ``` 并将文件另存为“metadata.json”。返回Filebase,将“metadata.json”文件上传到与我们上传图片相同的存储桶中。 ![https://upload-images.jianshu.io/upload_images/6687907-00ba22a9240cec00.png](https://upload-images.jianshu.io/upload_images/6687907-00ba22a9240cec00.png) 最后,点击CID并复制它,在下一部分中我们需要它来构建令牌URI以便铸造NFT: ![https://upload-images.jianshu.io/upload_images/6687907-32a5db002e467a32.png](https://upload-images.jianshu.io/upload_images/6687907-32a5db002e467a32.png) ## 铸造你的Goerli NFT 回到Remix,在“Deploy & Run Transactions”菜单下,进入“deployed contracts”,然后点击刚刚部署的合约,在打开的列表中,你会看到智能合约中包含的所有方法: ![https://upload-images.jianshu.io/upload_images/6687907-2231e885008435a2.png](https://upload-images.jianshu.io/upload_images/6687907-2231e885008435a2.png) **橙色方法**是实际写入区块链的方法,而**蓝色方法**是从区块链中学习的方法。 单击safeMint方法下拉图标,**粘贴您的地址**和以下字符串到uri字段中: `ipfs://\\` 单击转账将创建一个Metamask弹出窗口,提示您支付燃气费用。 点击“签名”并继续铸造您的第一个NFT! 等待几秒钟,为确保铸造成功,请将您的地址复制并粘贴到balanceOf方法输入中,并运行它 - 它应该显示您拥有1个NFT。 对于tokenUri方法,请使用“0”作为id参数进行相同操作,它应该显示您的tokenURI。 太棒了!您刚刚铸造了您的第一个NFT!🎉 现在是时候**转移到OpenSea**,检查元数据是否开始读取了。 ## 在OpenSea上可视化您的NFT 前往 [testnets.opensea.io](https://testnets.opensea.io/),使用您的Metamask钱包登录。然后点击您的个人资料图片,您应该会看到您新铸造的NFT。如果图片还没有显示出来,请点击它,然后点击“刷新元数据”按钮。 ![https://upload-images.jianshu.io/upload_images/6687907-c048d46b3c7181ec.png](https://upload-images.jianshu.io/upload_images/6687907-c048d46b3c7181ec.png) 有时候OpenSea很难识别测试网的元数据 - 可能需要长达6个小时才能看到。一段时间后,您的NFT应该会像这样显示:([https://testnets.opensea.io/assets/mumbai/0x5a411430964664412e69cff1134759f6bb57c5d7/1](https://testnets.opensea.io/assets/mumbai/0x5a411430964664412e69cff1134759f6bb57c5d7/1))。 ![https://upload-images.jianshu.io/upload_images/6687907-57cecfd6a72523f5.png](https://upload-images.jianshu.io/upload_images/6687907-57cecfd6a72523f5.png) 恭喜你成功地创建、修改并部署了你的第一个智能合约。铸造了你的第一个NFT并将你的图像发布到了IPFS上!🔥 下一步呢?为什么不修改你的智能合约,让用户只能铸造一定数量的NFT呢?每个用户只能铸造5个就足够了,否则有人可能会开始铸造成千上万的NFT! 为了做到这一点,请看一下映射类型,这里有一个[神奇的指南](https://www.alchemy.com/overviews/solidity-mapping),可以帮助你完成。 本文由[mdnice](https://mdnice.com/?platform=6)多平台发布
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容