truffle init 从零开始创建简单DApp项目
下面的部分软件需要翻墙。这里默认你已经会科学上网,不懂的可以自己搜索解决。
软件安装
chrome浏览器
metamask插件
在谷歌应用商店中搜索metamask
ganche(图形版)
nodejs和npm
下载地址
安装完成需要将node.exe所在路径加入环境变量PATH中
并且需要保证在cmd中可以使用node和npm命令,简单测试:
$ node -v
$ npm -v
开发环境配置
- 启动
ganache remix切换运行环境。点击remix在线编辑器右侧的run->Environment,选择Injected Web3metamask连接ganache。打开chrome浏览器中的metamask插件,首先通过12个单词短语恢复账号。然后通过"Custom RPC", 输入http://localhost:7545,保存并将换网络切换至http://localhost:7545,连接成功后显示主账户信息''
配置截图




Demo项目
$ mkdir demo
$ cd demo
$ npm init
后面全部enter默认选择(直接敲回车)就好了,效果如下:
$ ls
package.json
$ cat package.json
{
"name": "demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
$ npm install ethereum/web3.js --save
安装比较耗时, 需要耐心等待安装完成
完成后效果:
$ ls
node_modules/ package.json package-lock.json
$ ls node_modules/
bignumber.js/ crypto-js/ web3/ xmlhttprequest/
cookiejar/ utf8/ xhr2-cookies/
$ ls node_modules/web3/
bower.json example/ lib/ package.json styleguide.md
circle.yml gulpfile.js* LICENSE.md package-init.js
dist/ index.js package.js README.md
# 发现配置已经发生了改变
$ cat package.json
{
"name": "demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"web3": "github:ethereum/web3.js"
}
}
完整项目结构
在项目根目录下创建index.html和main.css
如下:
$ ls demo
index.html main.css node_modules/ package.json package-lock.json
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DApp Demo</title>
<link rel="stylesheet" type="text/css" href="main.css">
<script src="./node_modules/web3/dist/web3.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.js"></script>
</head>
<body>
<div class="container">
<h1>Simple DApp Demo</h1>
<h2 id="info"></h2>
<label for="name" class="col-lg-2 control-label">Name</label>
<input id="name" type="text">
<label for="age" class="col-lg-2 control-label">Age</label>
<input id="age" type="text">
<button id="button">更新个人信息</button>
</div>
<script>
window.addEventListener('load', function () {
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:7545"));
}
//web3.eth.defaultAccount = web3.eth.accounts[0];
// replace with your abi code
const abi = [
{
"constant": false,
"inputs": [
{
"name": "_name",
"type": "string"
},
{
"name": "_age",
"type": "uint256"
}
],
"name": "setPersonalInfo",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getPersonalInfo",
"outputs": [
{
"name": "",
"type": "string"
},
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
];
// replace with your contract address
const address = "0x0d4aed2bf6178c870355ce1100a11e8fafdbd15d";
// create contract instance
const PersonalInfo = web3.eth.contract(abi).at(address);
console.log("PersonalInfoContract:", PersonalInfo);
PersonalInfo.getPersonalInfo(function (error, result) {
if (!error) {
$("#info").html(result[0] + ' (' + result[1] + ' years old)');
console.log("get PersonalInfo success: ", result);
} else {
console.error("failed to get PersonalInfo :", error);
}
});
$("#button").click(function () {
var name = $("#name").val();
var age = $("#age").val();
PersonalInfo.setPersonalInfo(name, age, function (error, result) {
if (!error) {
// update label
$("#info").html(name + ' (' + age + ' years old)');
console.log("setPersonalInfo success: " + result);
} else {
consoe.log("fail to setPersonalInfo: " + error);
}
});
});
});
</script>
</body>
</html>
main.css
body {
background-color:#F0F0F0;
padding: 2em;
font-family: 'Raleway','Source Sans Pro', 'Arial';
}
.container {
width: 50%;
margin: 0 auto;
}
label {
display:block;
margin-bottom:10px;
}
input {
padding:10px;
width: 50%;
margin-bottom: 1em;
}
button {
margin: 2em 0;
padding: 1em 4em;
display:block;
}
#info {
padding:1em;
background-color:#fff;
margin: 1em 0;
}
使用web3.js和智能合约进行交互
使用solidity在线编辑器remix
solidity代码如下:
pragma solidity ^0.4.16;
contract PersonalInfo {
string name;
uint age;
function setPersonalInfo(string _name, uint _age) public {
name =_name;
age = _age;
}
function getPersonalInfo() public view returns(string, uint){
return (name, age);
}
}
使用metamask须知:
Due to browser security restrictions, we can't communicate with dapps running on file://. Please use a local server for development.
如果直接使用浏览器打开index.html会出现跨域访问,如下图:

遇到的问题:
The MetaMask Web3 object does not support synchronous methods like eth_sendTransaction without a callback parameter
官方解释:
All Async - Think of MetaMask as a light client
The user does not have the full blockchain on their machine, so data lookups can be a little slow. For this reason, we are unable to support most synchronous methods. The exceptions to this are:
- eth_accounts (web3.eth.accounts)
- eth_coinbase (web3.eth.coinbase)
- eth_uninstallFilter (web3.eth.uninstallFilter)
- web3.eth.reset (uninstalls all filters).
- net_version (web3.version.network).
解决方法:
在合约实例调用对应函数的时候,加上回调函数。形如:
PersonalInfoContract.setPersonalInfo(name, age, function (error, result) {
if (!error) {
// update label
$("#info").html(name + ' (' + age + ' years old)');
console.log("setPersonalInfo success: " + result);
} else {
consoe.log("fail to setPersonalInfo: " + error);
}
});
参考:
- https://coursetro.com/posts/code/99/Interacting-with-a-Smart-Contract-through-Web3.js-(Tutorial)
- https://truffleframework.com/docs/truffle/getting-started/creating-a-project
- https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md
- https://github.com/ethereum/wiki/wiki/JavaScript-API
- https://ethereum.stackexchange.com/questions/8736/how-to-call-my-contracts-function-using-sendtransaction
- https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html
- https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#dizzy-all-async---think-of-metamask-as-a-light-client
truffle init 从零开始创建简单DApp项目的更多相关文章
- Intellij创建简单Springboot项目
Intellij创建简单Springboot项目 第一步:选择创建新项目——file-new-project 第二步:选择项目类型——Spring Initializr-next 第三步:输入项目信息 ...
- 创建简单web项目
Intellij Idea直接安装(可根据需要选择自己设置的安装目录),jdk使用1.6/1.7/1.8都可以,主要是配置好系统环境变量,tomcat7上tomcat的官网下载压缩包解压即可. 一.创 ...
- Gradle——创建简单的项目
项目 & 任务 Gradle 的一切都是基于项目和任务的. 构建由一个或多个项目组成.项目的概念很抽象,它取决于你要用Gradle 做什么 .项目可以是 一个 Jar 库或者一个 web 程序 ...
- fir.im Weekly - 从零开始创建 Android 新项目
今年的 Google I/O 大会上,人工智能和虚拟现实的产品发布让我们对未来多了几分惊喜.对于开发者部分,Google 发布了 Android N 系统,感受最深的是全新的 Android Stud ...
- 使用Intellij Idea创建简单Maven项目(转)
我是学Java Web的,基本靠自学,在网上收集了各种视频资料,逐一的看,代码逐一的敲.学习了这么久之前一直未成想过要把自己的学习路程记录下来,在网上也看到过很多人把自己的学习历程以及遇到的问题写在了 ...
- 手动创建简单webpack项目及React使用
一.创建基本的webpack4.x项目 1.运行 npm init -y 快速初始化项目 2.在项目根目录创建src的源代码目录和dist产品目录 3.在src目录下创建 index.html 4.使 ...
- IDEA创建简单SpringBoot项目
环境:jdk 1.打开IDEA -->New --> Project -->Spring Initalizer-->next 2.此处,只做创建示例,所以next后Group等 ...
- IDEA创建简单SSM项目使用传统Jar包
#IDEA SSM项目使用传统Jar包 创建项目 下一步,命名 下一步,创建完成 下一步,创建资源文件夹resources 页面概览 左侧目录树 演示如下 一些简单的说明 其中包之间的层次调用 ent ...
- 创建简单Maven项目
目录: Maven基础构建概念.仓库.构建与部署 Maven作用 Maven项目install Maven安装配置.目录结构.配置文件 配置Maven默认本地仓库 Maven常见命令 使用Maven ...
随机推荐
- 斐讯 天天牛绑定教程 邀请码:8vozbf
天天牛邀请码 8vozbf 可以领取4代牛 最近斐讯推出了天天牛养成计划. 不过官方没有任何的指示教程,所以个人分享一个教程给大家. 1. 先把把旧的钱包备份一下 ,切记!! 而且一定要记得自己设的密 ...
- HTML+CSS水平垂直居中
啦啦啦,好了,今天来分享自己的第一个知识点,难得自己还能想起来过来博客园,写写博客的. 好了,言归正传,今天分享关于html和css的一个简单的知识点,对于大部分从事前端开发的人员来说可能都是很简单的 ...
- QTCPSOCKET 客户端已连接 而服务器无响应
最近在使用qt coding一个项目时,使用到了qtcpsocket模块来编写客户端与服务器.在windows平台下还能正常工作,但是在ubuntu平台下,客户端提示已连接时,服务器却没有响应.经过排 ...
- Datediff的使用(统计本日,昨日,本周,本月)
//统计本日,昨日,本周,本月添加的产品总数 //日期 DateTime DT = DateTime.Now; string day=DT.Date.ToS ...
- 【等价转换】—— min/max 的转换与互相转换
0. min 与 max 的转换 {max(X,Y)=X+Y−min(X,Y)min(X,Y)=X+Y−max(X,Y)min(X,Y)+max(X,Y)=X+Y" role="p ...
- 如何在Linux上设置SSH密码以进行无密码登录(转)
ssh(secure shell)广泛用于远程登录Linux服务器.当我们使用ssh登录到远程系统时,它会提示输入密码,然后只允许我们登录到服务器.有时我们需要配置应用程序或脚本(主要是shell脚本 ...
- 手动清除mac的广告弹框病毒 MacOSDefender
最近在浏览亚马逊, 京东的时候, 发现会自动弹出很多广告到浏览器, 其实是中了病毒MacOSDefender. 这个病毒非常烦人, 会在你浏览电商网页的时候拼命的打开广告页面, 而且还会弹出一些提示, ...
- python学习笔记-os模块参数
python的os 模块提供了非常丰富的方法用来处理文件和目录.常用的方法如下表所示: os.access(path, mode) 检验权限模式 os.chdir(path) 改变当前工作目录 os. ...
- tableview前端基础设计(初级版)
tableView前端基础设计 实现的最终效果 操作目的:熟悉纯代码编辑TableView和常用的相关控件SearchBar.NavigationBar.TabBar等,以及布局和基本功能的实现. 一 ...
- Apache HTTP 服务器 2.4(又名httpd)安装\配置 \启动
Apache HTTP 服务器 2.4 源文档