日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DAPP开发初探——永存的留言

發布時間:2025/7/25 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DAPP开发初探——永存的留言 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載地址

https://blog.csdn.net/qq_33764491/article/details/80570266

前言

最近DAPP的開發貌似很火,學習了區塊鏈的一些知識之后,相信有很多人和我一樣,也想了解開發一個DAPP是一個怎樣的流程。

下面將通過一個簡單的栗子來初識一下DAPP的開發流程,屆時,我們也將開發出第一個DAPP應用–《永存的留言》。

在線體驗(Ludis):http://words.ldsun.com/。

項目介紹

《永存的留言》是一個基于以太坊的在線留言平臺。它的功能十分簡單–用戶可以在平臺上進行留言,平臺每10s隨機的展示留言內容。
但是它的特點在于,利用區塊鏈的特性,保證了數據的真實性、完整性和安全性。

  • 使用Solidity開發后端方法
  • 使用Truffle框架
  • 基于unbox react腳手架項目
  • 部署在以太坊測試網絡上Ropoetn Test Network
  • 使用MetaMask錢包插件發布交易

開發步驟

下載react項目模板

確保本地已經準備好Truffle所需的環境,準備以下命令,下載react項目模板。
$ mkdir a && cd a
truffle unbox react
當看到 Unbox successful. Sweet!提示時,表明下載成功。

編寫智能合約

這是我們唯一的實現合約,包含的發送留言和讀取留言的方法。

pragma solidity ^0.4.19;contract SimpleStorage {// 留言結構體struct Message {string word; // 留言address from; // 留言者地址string timestamp ; // 留言unix時間戳}Message[] private wordArr;/*** 寫入留言的方法*/function setWord(string s, string t) public {wordArr.push(Message({word: s,from: msg.sender,timestamp: t}));}/*** 獲取隨機留言的方法*/function getRandomWord(uint random) public view returns (uint, string, address, string) {if(wordArr.length==0){return (0, "", msg.sender, "");}else{Message storage result = wordArr[random];return (wordArr.length, result.word, result.from, result.timestamp);}} }

編譯、部署合約

修改發布的腳本。

var SimpleStorage = artifacts.require("./SimpleStorage.sol"); //var Words = artifacts.require("Words");module.exports = function(deployer) {deployer.deploy(SimpleStorage);//deployer.deploy(Words); };

執行truffle compile進行合約的編譯。

獲取合約地址。

  • 這里我們打開MetaMask錢包插件,左上角選擇Ropoetn Test Network網絡.
  • 利用Remix編譯,發布合約到以太坊測試環境。
  • 通過MetaMask的交易hash查詢,獲取已經部署到以太坊測試網絡中的合約地址。

編寫前端頁面

這個部分主要是編寫前端的展示效果和與合約交互的邏輯,這一部分最難編寫,也最耗時間。

  • 主要邏輯代碼
const contractAddress = "0x39e5196750dcddb1aaf6dda7d6e8dbb633482905" // 合約地址(以太坊測試網絡) var simpleStorageInstance // 合約實例class App extends Component {// 初始化構造constructor(props) {super(props)this.state = {word: null,from: null,timestamp: null,random: 0,count: 0,input: '',web3: null,emptyTip: "還沒有留言,快來創建全世界第一條留言吧~",firstTimeLoad: true,loading: false,loadingTip: "留言正在寫入,請耐心等待~",waitingTip: "留言正在寫入,請耐心等待~",successTip: "留言成功",animate: "",in: css(styles.in),out: css(styles.out)}}// 獲取Web3實例componentWillMount() {// Get network provider and web3 instance.getWeb3.then(results => {this.setState({web3: results.web3})// Instantiate contract once web3 provided.this.instantiateContract()}).catch(() => {console.log('Error finding web3.')})}// 獲取合約實例instantiateContract() {/** SMART CONTRACT EXAMPLE** Normally these functions would be called in the context of a* state management library, but for convenience I've placed them here.*/const contract = require('truffle-contract')const simpleStorage = contract(SimpleStorageContract)simpleStorage.setProvider(this.state.web3.currentProvider)// Get accounts.this.state.web3.eth.getAccounts((error, accounts) => {simpleStorage.at(contractAddress).then(instance => {simpleStorageInstance = instance/*simpleStorage.deployed().then((instance) => {simpleStorageInstance = instance // 部署本地Ganache*/console.log("合約實例獲取成功")}).then(result => {return simpleStorageInstance.getRandomWord(this.state.random)}).then(result => {console.log("讀取成功", result)if(result[1]!=this.setState.word){this.setState({animate: this.state.out})setTimeout(() => {this.setState({count: result[0].c[0],word: result[1],from: result[2],timestamp: result[3],animate: this.state.in,firstTimeLoad: false})}, 2000)}else{this.setState({firstTimeLoad: false})}this.randerWord()})})}// 循環從區塊上隨機讀取留言randerWord() {setInterval(() => {let random_num = Math.random() * (this.state.count? this.state.count: 0)this.setState({random: parseInt(random_num)})console.log("setInterval讀取", this.state.random)simpleStorageInstance.getRandomWord(this.state.random).then(result => {console.log("setInterval讀取成功", result)if(result[1]!=this.setState.word){this.setState({animate: this.state.out})setTimeout(() => {this.setState({count: result[0].c[0],word: result[1],from: result[2],timestamp: result[3],animate: this.state.in})}, 2000)}})}, 10000)}// 寫入區塊鏈setWord(){if(!this.state.input) returnthis.setState({loading: true})let timestamp = new Date().getTime()simpleStorageInstance.setWord(this.state.input, String(timestamp), {from: this.state.web3.eth.accounts[0]}).then(result => {this.setState({loadingTip: this.state.successTip})setTimeout(() => {this.setState({loading: false,input: '',loadingTip: this.state.waitingTip})}, 1500)}).catch(e => {// 拒絕支付this.setState({loading: false})})}// 時間戳轉義formatTime(timestamp) {let date = new Date(Number(timestamp))let year = date.getFullYear()let month = date.getMonth() + 1let day = date.getDate()let hour = date.getHours()let minute = date.getMinutes()let second = date.getSeconds()let fDate = [year, month, day, ].map(this.formatNumber)return fDate[0] + '年' + fDate[1] + '月' + fDate[2] + '日' + ' ' + [hour, minute, second].map(this.formatNumber).join(':') }/** 小于10的數字前面加0 */formatNumber(n) {n = n.toString()return n[1] ? n : '0' + n}}

運行項目

使用npm start啟動項目,瀏覽器的3000端口運行。
效果如下(一定要連接到Ropoetn Test Network網絡才可以)。

總結

這樣我們就開發出了我們的第一個DAPP,體會了開發的基本流程。

  • 明確項目需求
  • 確定開發環境
  • 編寫、測試、部署合約
  • 設計前端頁面,使前后端交互
  • 發布測試

項目源碼

GitHub

參考文章

Ludis的博文

轉載于:https://www.cnblogs.com/qq874455953/p/10264443.html

總結

以上是生活随笔為你收集整理的DAPP开发初探——永存的留言的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。