欢迎访问 生活随笔!

生活随笔

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

编程问答

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

发布时间:2025/7/25 编程问答 42 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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开发初探——永存的留言的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。