以太坊web3开发初步学习
以太坊web3开发初步学习
此文是对https://learnblockchain.cn/2018/04/15/web3-html/的学习再理解。
以太坊智能合约通过使用web3.js前端和智能合约交互。web3.js是以太坊官方的js API, 用户可以通过web3.js提供的API通过http或者IPC与
本地的或者远程的以太坊节点进行交互。
主要有以下几种库
web3-eth //主要用来与以太坊和智能合约交互
web3-shh //用于控制whisper协议和p2p通信以及广播
web3-utils // 包含与DApp有关的功能
web3和geth(以太坊客户端)通信使用的是JSON—RPC协议。
首先以一个最基础的solidity合约举例:
pragma solidity ^0.4.21;
contract InfoContract {
string fName;
uint age;
function setInfo(string _fName, uint _age) public {
fName = _fName;
age = _age;
}
function getInfo() public constant returns (string, uint) {
return (fName, age);
}
}
web3 provider是指自定义节点,例如私有测试网络。
Injected web3 连接到嵌入页面的web3,比如连接到MetaMask。
Javascript VM是本地的js虚拟机环境,仅用于练习合约编写。
接着就是安装web3。web3安装好之后创建UI前端,包括了输入框。
在<script>
标签中间写web.js的代码和智能合约进行交互。
<script>
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));
}
</script>
该脚本意思为,如果web3已被定义,就创建web3对象。否则就手动指定provider。
provider就是钱包,通过RPC web3和钱包进行连接。
一旦连接钱包,接下来便可以设置以太坊账户。
web3.eth.defaultAccount = web3.eth.accounts[0];//选择第一个账户。
账户设置好之后,web3通过ABI调用合约函数,通过Remix中出现的ABI,
info.getInfo(function(error, result){//info是某地址的合约
if(!error)
{
$("#info").html(result[0]+' ('+result[1]+' years old)');
console.log(result);
}
else
console.error(error);
});
$("#button").click(function() {//setInfo是info合约的函数,点击button后设置了name和age的值
info.setInfo($("#name").val(), $("#age").val());
});
最终,合约向以太坊中输入了name和age。
小结
以太坊智能合约,本质上就像一个类库, 类库的方法用于操作和更新类库中的状态变量,这些方法需要外部用户来调用。外部用户调用ABI的时候往往会向其中输入参数。
这些参数用于更新合约的全局变量。 所以说智能合约的本质是不可篡改的数据库。智能合约的核心就是其状态变量。
其实智能合约本质就是一个难以篡改的数据库。称之为合约实际上真是误导人。
其他知识点
$("#xxid")是id选择器。jquery的知识。
https://www.cnblogs.com/jokerjason/p/7404649.html
solidity的事件
区块链是打包一系列交易的区块组成的链条,每一条交易会包含0到多个日志记录,日志就代表着合约所触发的事件。
DAPP的应用,如果监听了某事件,当事件发生时,会进行回调。日志和事件在合约内无法被访问,而只能被外部监听。
事件的定义:
event EventName(address bidder, uint amount)
该用法和定义函数式一样的,并且在事件合约中同样可以被继承。
事件监听有什么用?
定义一个事件,
event Instructor(string name, uint age); //接收两个参数
在setInfo函数中,触发Instructor事件。
function setInfo(string _fName, uint _age) public{
fName = _fName;
age = _age;
emit Instructor(_fName, _age);//这是setInfo的参数。
}
emit表示触发动作。 setInfo函数执行时会触发该事件。在web3前端输入name和age之后,触发Instructor事件
在web3部分引用事件监听器
var instructorEvent = info.Instructor();
再写一个回调函数, 这样,代码更新后,再在浏览器上点击update info,便会回调
instructorEvent.watch(function(error, result) {//该函数有两个返回值,result便是setInfo的返回值。
if (!error)
{
$("#info").html(result.args.name + ' (' + result.args.age + ' years old)');//这里写的是形参。
} else {
console.log(error);
}
});
说白了, event变量写好后,在某个函数中声明,触发的时候, web3如果监听了它,且写了一个watch函数,便可以得到监听的参数。
这些参数拿到之后再输出到页面上,从而完成更新。
solidity的事件和日志
var options = {
fromBlock: 0,
address: web3.eth.defaultAccount, //地址
topics: ["0x0000000000000000000000000000000000000000000000000000000000000000", null, null]
};
web3.eth.subscribe('logs', options, function (error, result) {
if (!error)
console.log(result);
})
.on("data", function (log) {
console.log(log);
})
.on("changed", function (log) {
});
solidity局部变量无法使用映射类型。
有两个函数,funcA和funcB, 在funcA中声明了一个变量C,funcA调用B且C作为B的参数,但是总是报错。
后来查资料发现对memory 类型的映射赋值,会报错。https://blog.csdn.net/qq_33764491/article/details/80403603
原因在于solidity的映射的实现是通过
solidity枚举类型
和C语言枚举类型的写法一样。
enum weekday{
sun,mon,tue,wed,the,fri,sat;
}
// weekday.sun 来引用枚举值。
注意,"}"后面没有分号。 使用枚举的时候要是xxx.xxx格式。
solidity异常通知
一共有三种,
assert(bool condition), //如果条件不满足,抛出异常,合约中断,一般使用于内部错误
require(bool condition) //如果条件不满足,抛出异常,合约中断, 用于函数参数输入的判断和外部函数使用
require(bool condition, string message) //会抛出日志
revert() //回滚, 合约中断, 回滚状态改变
revert(string, reason) //提供一个回滚说明
监控器检测到异常之后,要用哪类通知呢?
这里选择了assert(bool condition)
assert(Parse_acceptword_to_wordset(accept_word, wset) != RETURNID.ACCEPT_WORD_FORMAT_WRONG);
solidity比较字符串大小
几乎能搜到的写法都是错误的。不知道是由于solidity的abi库改变了还是别的原因。查看文档发现,要得到字符串的hash值,必须先调用abi.encodePacked()
keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2))
文档建议最好使用bytes来代替string,这样最节省gas。
solidity无法使用while(1)
while(1)用法错误,应该使用while(true)
solidity的日志
事件是给solidity使用的,于是会有一种比较特殊的方案。
对外访问,在函数的函数名xx()之后添加
solidity日志(Event)的使用方法。
在DAPP的应用中,如果监听了某事件,当某事件发生时,会进行回调。 但是日志在合约内是无法被访问的,即使是创建日志的合约。
event eventName(address bidder, uint amount)//
使用web3.js和日志进行交互,如果它发生了错误。
首先要定义一个事件,该事件要能够和合约进行触发
参考资料 https://www.cnblogs.com/tinyxiong/p/9045274.html
以太坊web3开发初步学习的更多相关文章
- 基于Vue、web3的以太坊项目开发及交易内幕初探 错误解决总结
基于Vue.web3的以太坊项目开发及交易内幕初探 本文通过宏观和微观两个层面窥探以太坊底层执行逻辑. 宏观层面描述创建并运行一个小型带钱包的发币APP的过程,微观层面是顺藤摸瓜从http api深入 ...
- 以太坊 web3.js 文档翻译及说明
这些天,为了录制以太坊DAPP开发实战课程,我准备把web3文档全部翻译一下(并做适当的补充),目前web3.js 0.20.x 版本 已经翻译完成,欢迎大家前往查阅. 这里还几个实用DEMO,供大家 ...
- 以太坊钱包开发系列4 - 发送Token(代币)
以太坊去中心化网页钱包开发系列,将从零开始开发出一个可以实际使用的钱包,本系列文章是理论与实战相结合,一共有四篇:创建钱包账号.账号Keystore文件导入导出.展示钱包信息及发起签名交易.发送Tok ...
- 以太坊钱包开发系列2 - 账号Keystore文件导入导出
以太坊去中心化网页钱包开发系列,将从零开始开发出一个可以实际使用的钱包,本系列文章是理论与实战相结合,一共有四篇:创建钱包账号.账号Keystore文件导入导出.展示钱包信息及发起签名交易.发送Tok ...
- 以太坊RLP用法-go-ethereum学习
RLP (递归长度前缀)提供了一种适用于任意二进制数据数组的编码,RLP已经成为以太坊中对对象进行序列化的主要编码方式.RLP的唯一目标就是解决结构体的编码问题:对原子数据类型(比如,字符串,整数型, ...
- 关于书籍《区块链以太坊DApp开发实战》的内容告示
书中所列举的以太坊 etherscan 浏览器,原链接已经不能使用国内网络正常访问了,需要翻墙,下面的链接不需要翻墙,也是 etherscan 的官方浏览器链接: 以太坊浏览器:https://cn. ...
- 如何从零开始学习区块链技术——推荐从以太坊开发DApp开始
很多人迷惑于区块链和以太坊,不知如何学习,本文简单说了一下学习的一些方法和资源. 一. 以太坊和区块链的关系 从区块链历史上来说,先诞生了比特币,当时并没有区块链这个技术和名词,然后业界从比特币中提取 ...
- 以太坊(ethereum)开发DApp应用的入门区块链技术教程
概述 对初学者,首先要了解以太坊开发相关的基本概念. 学习以太坊开发的一般前序知识要求,最好对以下技术已经有一些基本了解: 一种面向对象的开发语言,例如:Python,Ruby,Java... 前 ...
- 基于以太坊开发的类似58同城的DApp开发与应用案例
今天,Origin开发团队很高兴地宣布在以太坊Rinkeby测试网络上推出Origin Protocol Demo DApp ! 在这个DApp中,你可以在不同垂直行业的solidarity econ ...
随机推荐
- C++模板简介
模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数.返回值取得任意类型. 模板是一种对类型进行参数化的工具: 通常有两种形式:函 ...
- Qt5之事件学习总结
首先要明白一个概念,事件和信号并不一样,比如单击一下鼠标,就会产生鼠标事件(QMouseEvent),是对这个动作的描述,而因为按钮被按下了,按钮会发出clicked()的单击信号(是按钮控件产生的) ...
- SpringBoot整合定时任务----Scheduled注解实现(一个注解全解决)
一.使用场景 定时任务在开发中还是比较常见的,比如:定时发送邮件,定时发送信息,定时更新资源,定时更新数据等等... 二.准备工作 在Spring Boot程序中不需要引入其他Maven依赖 (因为s ...
- 20210716 noip17
考场 终于有一场在晚上考了 T1 随便画了画就发现要求每个点的后继个数,想起来有 dfs 和 toposort 两种方法,感觉很稳 T2 裸的网络流有 70pts?!真香 一看 T3 就想起了 Mst ...
- CSP 2021 游记
\(\text{Day -INF}\) 看见了 \(\text{SCP2021}\) 的报名通知,想着应该教练会让我们统一报名,就没放在心上 然后-- 然后过了二十多天教练根本没有提报名的事情,搞得我 ...
- Linux 学习路线
前言 这篇文章会一直更新...只是将个人的文章总结归纳到这,不代表最佳学习路线 没有链接的文章后续会补上...还没写的知识点未来用到也会补上...太卷了 常用基础命令 Linux常用命令 - cd命令 ...
- AQS学习(二) AQS互斥模式与ReenterLock可重入锁原理解析
1. MyAQS介绍 在这个系列博客中,我们会参考着jdk的AbstractQueuedLongSynchronizer,从零开始自己动手实现一个AQS(MyAQS).通过模仿,自己造轮子来学习 ...
- POJ3061——Subsequence(尺取法)
Subsequence POJ - 3061 给定长度为n的数列整数a0,a1,a2-an-1以及整数S.求出总和不小于S的连续子序列的长度的最小值,如果解不存在输出0. 反复推进区间的开头和末尾,来 ...
- Python爬无止境,获得王者荣耀全部高清皮肤
作为一名热爱王者两年的程序员,早就想爬取所有英雄皮肤的高清照片,在设个幻灯片放映,真香,这次只用16行代码就能实现,对于新手拿这个作为实战练手项目既简单又容易上手,快来尝试下. 百度"王者荣 ...
- 深入学习Composer原理(三)
本系列第三篇文章,一起了解下PSR规范中的PSR4和PSR0规范 首先恭喜大家,包括我自己,坚持到了现在.这篇文章之后,Composer的基础原理就清晰明了咯.也就是说,Composer所利用的正是s ...