DAPP学习笔记——web3.js篇

第五课

处探DApp总结
关键点:DAPP关键是web3和智能合约交互
不足:
1.使用以太坊网络,交易确认慢,消耗账户以太币
2.需要搭建web服务器
3.不易修改,测试,调试,发布应用。

为了解决这些问题我们采取了学习:
1⃣️使用本地节点Ganache
2⃣️web3.js的原理和使用
3⃣️使用开发框架truffle

第六课

Web服务器搭建
最主流的使用:Nginx/Apache
或者用集成的方法:
如在mac下可以下载MAMP
1.MAMP:集成了Mac+Apache+Mysql+Php
2.或者应用Python启动一个f服务器节点
python -m SimpleHTTPServur会返回一个8000端口
在浏览器中输入http://127.0.0.1:8000/ 即可启动
3.利用npm先安装好npm lite-server启动npm run dev即可

第9课:官方节点Geth 安装(私有链已掌握


Geth:go-ethereum以太坊节点官方的go语言实现版本
Mac下:使用brew 安装 brew是Mac下的包安装工具
在geth下创建私有链之前有写过博客。

在Geth下使用API服务:1.HTTP RPC22.Web Socket 3.IPC默认开启

第15课:Geth 节点集群(联盟链)后面还要去补充

这节课讲
开启多个节点。
本地测试注意点:
1.每个节点都有不同的datadir
2.每个节点要运行在不同
多节点建立连接。admin.addPeer

把webservice部署到自己的服务器上。不要放本地,以后到服务器上去调用。

第17课 Dapp中使用web3对象

需要注意的
1.使用web3对象:如果使用本地节点,可以使用同步接口,否则大部分接口仅能使用异步接口,传递一个回调函数作为最后一个参数,回调函数使用error-first风格。
例:异步接口
web3.eth.getBlock(58,function(error,result){
if(!error){
console.log(JSON.stringify(result));
}
else{
console.log(error);
}

});

第18课Web3.js API使用

主要还是得自己去看api文档
主要需要用到的4个常用api接口
1.检查环境

** (观察matemask是否安装**)

DAPP学习笔记——web3.js篇_第1张图片

检查当前网络环境是否匹配:DAPP学习笔记——web3.js篇_第2张图片
针对第一种的一个demo代码:
DAPP学习笔记——web3.js篇_第3张图片
DAPP学习笔记——web3.js篇_第4张图片

id=env显示当前环境。net显示当前网络
2.发送交易
检查钱包是否解锁
DAPP学习笔记——web3.js篇_第5张图片
解锁之后就可以发送交易。否则不可以发送交易。
实现一个具体的转账的Demo。效果图如下
DAPP学习笔记——web3.js篇_第6张图片
具体实现代码如下:结合ganache使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>转账Demo</title>
    <link rel="stylesheet" type="text/css" href="main.css">
<!--分割线-->
</head>
<!--html-->
<body>

		<!--这里是展示智能合约2传来的数据-->
		<div class="container">
			<h1>转账 Demo</h1>
			<h2 id="env"></h2>
			<h2 id="account"></h2>
			<label>源账户:</label>
			<input type="text" id="fromAccount" value="">
			<label>*目标账户:</label>
			<input type="text" id="toAccount" value="">
			<label>*转账金额(ether):</label>
			<input type="text" id="amount" value="0.1">
			<label>*Gas limit(gas):</label>
			<input type="text" id=gaslimit value="21000">
			<label>*Gas 价格(Gwei):</label>
			<input type="text" id="gasprice" value="5">
		
			<button onclick="sendTransaction()">发送:</button>
			<div id="transactionResponse"></div>

		</div>
	<!--js代码-->
	<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
	<script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>

	<script type="text/javascript">
	</script>
    <script>

       // Our future code here..
	   //查看web3是否安装metamask
		window.addEventListener('load',function(){
			if(typeof web3!='undefined'){
				web3=new Web3(web3.currentProvider);
				if(web3.currentProvider.isMetaMast==true){
					$("#env").html("MetaMask可用");
					console.log("MetaMask可用");
				}else{
					$("#env").html("非MetaMask可用");
					console.log("非MetaMask可用");
				}
			}else{
				$("#env").html("No web3? 需要安装	Metamask!");
			}
		
		});
		//查看钱包是否解锁
		web3.eth.getAccounts(function(err,accounts){
			if(accounts.length==0){
				$("#account").html("请检查钱包是否解锁");
				console.log("请检查钱包是否解锁");
			}else{
				$("#account").html("钱包已经解锁");
				console.log("钱包已经解锁");
			}
		});
		//发送转账
		function sendTransaction(){
			var fromAccount=$('#fromAccount').val();
			var toAccount=$('#toAccount').val();
			var amount=$('#amount').val();
			var gas=$('#gaslimit').val();
			var gasprice=$('#gasprice').val();
			//判断输入的信息合法有效
			if(web3.isAddress(fromAccount) && web3.isAddress(toAccount) && amount != null
			&& amount.length>0 && gas!=null && gas.length>0 && gasprice!=null && gasprice.length>0
			){
				//Example2 :使用默认账户
				// web3.eth.defaultAccount=fromAccount;
				var message={from:fromAccount,to:toAccount,value:web3.toWei(amount,'ether')};
				console.log(message);
				web3.eth.sendTransaction(message,(err,res)=>{
					var output=""
					if(!err){
						output+=res;
					}else{
						output="error";
					}
					document.getElementById('transactionResponse').innerHTML="Transaction response= " +output +"
"
; }); } } </script> </body> </html>

略修改了一下视频代码:1.让当前登陆账户展示。2.fromAccount为当前登陆账户,转账时fromAccount为当前登陆账户,无需在输入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>转账Demo</title>
    <link rel="stylesheet" type="text/css" href="main.css">
<!--分割线-->
</head>
<!--html-->
<body>

		<!--这里是展示智能合约2传来的数据-->
		<div class="container">
			<h1>转账 Demo</h1>
			<h3 id="env"></h3>
			<h3 id="account"></h3>
			<label>当前账户:</label>
			<h3 id="fromAccount" ></h3>

			<label>*目标账户地址:</label>
			<input type="text" id="toAccount" value="">
			<label>*转账金额(ether):</label>
			<input type="text" id="amount" value="0.1">
			<label>*Gas limit(gas):</label>
			<input type="text" id=gaslimit value="21000">
			<label>*Gas 价格(Gwei):</label>
			<input type="text" id="gasprice" value="5">
		
			<button onclick="sendTransaction()">发送:</button>
			<div id="transactionResponse"></div>

		</div>
	<!--js代码-->
	<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
	<script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>

	<script type="text/javascript">
	</script>
    <script>

       // Our future code here..
	   //查看web3是否安装metamask

		window.addEventListener('load',function(){
			if(typeof web3!='undefined'){
				web3=new Web3(web3.currentProvider);
			
				if(web3.currentProvider.isMetaMast==true){
					$("#env").html("MetaMask可用");
					console.log("MetaMask可用");
				}else{
					$("#env").html("非MetaMask可用");
			
					console.log("非MetaMask可用");
				}
			}else{
				$("#env").html("No web3? 需要安装	Metamask!");
			}
		
		});
		//查看钱包是否解锁
		web3.eth.getAccounts(function(err,accounts){
			if(accounts.length==0){
				$("#account").html("请检查钱包是否解锁");
				console.log("请检查钱包是否解锁");
			}else{
				$("#account").html("钱包已经解锁");
				console.log("钱包已经解锁");
			}
		});
		//查看当前账户及余额
		var accounts=web3.eth.accounts;
		web3.eth.getAccounts(function callback1(error,result){
			console.log("result[0]"+result[0]);
			$("#fromAccount").html(result[0]);
		//  web3.eth.getBalance(result[0],function callback2(err2,value){
		// 	 test=web3.fromWei(value, 'ether');
		// 	 console.log("value="+test);
		//  });
		});
		//发送转账
	
		function sendTransaction(){
			fromAccount=web3.eth.defaultAccount;
			var toAccount=$('#toAccount').val();
			var amount=$('#amount').val();
			var gas=$('#gaslimit').val();
			var gasprice=$('#gasprice').val();
			//判断输入的信息合法有效
			if(web3.isAddress(fromAccount) && web3.isAddress(toAccount) && amount != null
			&& amount.length>0 && gas!=null && gas.length>0 && gasprice!=null && gasprice.length>0
			){
				//Example2 :使用默认账户

			
				var message={from:fromAccount,to:toAccount,value:web3.toWei(amount,'ether')};
				console.log(message);
				web3.eth.sendTransaction(message,(err,res)=>{
					var output=""
					if(!err){
						output+=res;
					}else{
						output="error";
					}
					document.getElementById('transactionResponse').innerHTML="Transaction response= " +output +"
"
; }); } } </script> </body> </html>

3.合约部署,加载合约
合约相关的主要调用代码就是这个
主要示例代码:DAPP学习笔记——web3.js篇_第7张图片
之后可以通过info.functionname去调用合约的函数。这个我们再做第一个Dapp 的Demo就了解过这个。

如果调用的是只返回值view类型的function我们可以用.call。如果需要传值进去就用sendTransaction。
具体来说。我们第一个Demo展示名字年龄:info.getInfo.call(function(error,result){})
如果是传入名字年龄则用info.setInfo.sendTransaction(KaTeX parse error: Expected 'EOF', got '#' at position 3: ("#̲"name).val(),("#"age).val(),{gas:220000},function(error,result) 可以自己设置需要的gas费,需要注意的是我们有一个要求最低大于210000

但是这里需要我们手动再代码那填写合约代码。我们也可以设置自动编译**(第二十课。字节码在哪看?暂时没找到,回头再搞)**

第21课:监听合约事件刷新UI界面

这节课主要是讲如何监听合约事件,个人认为非常重要且有帮助。事件是合约和外部交流的一个接口,因为在调用合约的时候都是异步执行的。这意味着,我们在调用一个函数时是没办法拿到结果的。如果我们想要拿到结果就得用到事件日志。
DAPP学习笔记——web3.js篇_第8张图片

具体代码展示:
合约代码如下

pragma solidity ^0.4.26;

contract InfoContract {
    
   string Name;
   uint age;
   string content;
   event Instructor(
       string name,
       uint age
    );

   function setInfo(string _Name, uint _age) public {
       Name = _Name;
       age = _age;
       emit Instructor(_Name, _age);
   }
   
   function getInfo() public view returns (string,uint) {
       return (Name,age);
   }   

}



针对这个合约的Instructor事件我们拿到监听的结果的方法。
1.var infoContract = web3.eth.contract(abi)abi为函数的abi码
2. var info= infoContract.at(合约地址)
3. 调用监听事件

			var infoEvent=info.Instructor();
			infoEvent.watch(function(error,result){
				if(!error){
					$("#loader").hide();
					$("#info").html(result.args.name+'('+result.args.age+')years old');
				}else{
					$("#loader").hide();
					$("#info").html('Error'+error);
				}
			});

需要特别注意的是1.监听用watch 2.取值不是直接用result。而是result.args.监听对象名称。

第22课 Web3.js使用总结

1.web3.js有两个版本1.0和2.0.我们默认的是2.0版本。1.0还是测试版本
2.web3.js调用大部分是异步的,我们需要通过回调拿到结果
3.如果我们用了metamask。metamask要用站点的方式访问,也就是要用服务器。方法有好几种,前面有提到。目前我是用node,npm run dev启动。
4.多看文档

你可能感兴趣的:(dapp)