区块链与DApp开发(学习总结)
0 区块链认知
开发区块链与Dapp所需知识
GO 语言: 联盟链、私有链的搭建,设立接口、监听
Solidity语言: 智能合约开发,区块链上的逻辑实现
Node.js : 监听、通信、RPC
JavaScript : Dapp应用程序开发
<学习资料>
- Linux: 《linux从入门到精通》
- JavaScript: 《JavaScript编程精解》
- 以太坊: 《深入理解以太坊》、《第一行代码以太坊》、以太坊源码
- Go: 《GO语言实战》《GO并发编程实战》
- Solidity与智能合约: 《Solidity编程》《深入以太坊智能合约开发》
- 区块链: 《GO语言公链开发实战》
- 网络与前端:《node.js区块链开发》(利用node深度使用区块链功能)《零基础学微信小程序开发》
- Dapp实战: 《区块链以太坊Dapp开发实战》(GO+solidity)、《区块链Dapp》(JS+Solidity)、《区块链开发实战实用案例分析》(案例应用多但需要基础 Solidity+JS)、《区块链智能合约与Dapp应用实战》(solidity+Java)
现在市面上的区块链书很多、很杂,学习难度也相差很大。在走了一些弯路后,本人翻阅了这些书的主要内容、记录了每本书的主要侧重点与讲述较好的地方,并给出如下的阅读建议。并非要全部通读,尤其在有了一定基础之后可直接阅读书中的核心部分。
有了此相对平滑的学习曲线,相信你我在自学的路上一定能越走越远。祝你成功!
建议学习顺序(我目前还在5):
1. 《JavaScript编程精解》(掌握JS的基本编程)2. 《Solidity编程》(掌握智能合约的基本编程)3. 《区块链以太坊Dapp开发实战》 《GO语言实战》(参考) (学习GO的RPC接口链接以太坊)4. 《深入理解以太坊》(此时学习以太坊内部的细节更易于理解)5. 《第一行代码以太坊》(学习通过web3接口链接以太坊)6. 《区块链Dapp》(Dapp完整实战)7. 《区块链开发实战实用案例分析》(更复杂更多元的项目)《深入以太坊智能合约开发》(参考避免重复造轮子)8. 《node.js区块链开发》(开放了更多功能,不再局限于只使用接口)9. 《GO语言公链开发实战》《GO并发编程实战》(完全解开手脚,不再局限于别人的链,订制自己的联盟链、企业链)
实际应用项目
电子身份、证据认证系统
供应链上下游智能合约
网上拍卖软件
众筹平台
融资、股份认证等
<区块链知识>
部署私有链
Ganache
使用Ganache图形界面端或ganache-cli快速搭建私有链,使用图形界面可快速监控链上的实时交易。
给出一个win下exe格式的下载链接:ganache图形界面下载地址
账户管理
MetaMask
Mist钱包已经停用,使用轻度的MetaMask钱包管理主网、测试网、私有链中的账户
生成以太坊钱包
使用以太坊源码调用创建账户的函数,地址将保存在keystore下
再使用解码函数传入密码从中解出私钥(交易签名、导入其他钱包时使用)
//存储钱包文件的位置keydir := "./keystores"//调用源码ks := keystore.NewKeyStore(keydir,keystore.StandardScryptN,keystore.StandardScryptP)wallet,err := ks.NewAccount(password)
发布智能合约
remix:
- JavaScript VM虚拟机,测试合约函数功能使用
- 注入web3 向主网、测试网发布合约。此时在remix网页下打开metamask插件选择对应网络可自动切换
- web3自定义网络, 可连接到私有链
Truffle:
- 在truffle中新建工程
init
并导入到ganache的项目中 - 在配置文件中配置网络连接位置,一般为私有链测试
- sol文件复制进合约文件夹,同时编译文件夹中生成编译文件(仿写案例,注意文件名序号递增)
build
编译当前工程内的所有sol文件migrate
部署智能合约进当前网络
给出Truffle官方文档https://www.trufflesuite.com/docs/truffle/overview
<智能合约知识>
编写智能合约
remix
使用网页版remix编写智能合约
中文版remix网站 http://remix.hubwiz.com/
英文版remix网站 http://remix.ethereum.org
建议使用英文版,因为中文版可能存在以太坊测试网络连不上的问题
配合atom保存到本地
事件与监听
智能合约无法自动触发,只能通过外部调用。所以智能合约只能发布事件,但不能监听。
发布的事件数据储存在该交易(函数调用)的日志中,如下图所示为满足ERC20协议的Transfer交易触发的交易事件。
LOG由address、Topic、Data三部分组成
- Address: 代表发布事件的合约地址
- Topic:第一个数据为事件触发的函数头的HASH值,如上图中数据内容为:
sha3('Transfer(address,uint256)')
- Data:触发事件传出的参数,此事件触发后返回三个值为from,to,value(ERC20协议)
同时,在solidity中定义事件时给出indexed关键字则参数将保存在topic中,而不存在data中,更有利于筛选事件:
event Transfer(address indexed from,address indexed to, uint256 value)
则Topic将出现3行数据,分别为函数头hash,传出参数1 from,参数2 to
函数ID生成方法
用Keecak256算法给函数声明字符串进行hash,取结果的前四个字节:
bytes4(keccak256(Transfer(address,uint256)))
ERC20协议
加密货币协议,可用于股权证明、众筹证明等一切权益共识
ERC271协议
加密猫所用的协议,唯一个体币协议
<与区块链交互>
<<利用GO
查询区块链消息
开发环境 :GO
- 导入以太坊源码包、所有依赖包并配置gcc编译器
rpcClient,err := rpc.DialHTTP(erc.NodeUrl)
配置以太坊RPC接口
接口协议
采用json结构传输数据,如获取交易信息 methodName := "eth_getTransactionByHash"
的输出结构:
type Transaction struct {Hash string `json: "hash"`Nonce string `json: "nonce"`BlockHash string `json: "blockHash"`BlockNumber string `json: "blockNumber"`TransactionIndex string `json: "transactionIndex"`From string `json: "from"`To string `json: "to"`Value string `json: "value"`GasPrice string `json: "gasPrice"`Gas string `json: "gas"`Input string `json: "input"`}
更多接口方法查询以太坊JSON RPC手册 http://cw.hubwiz.com/card/c/ethereum-json-rpc-api/1/3/19/
以太坊RPC接口nodeURL:
免费的节点调用网站:https://infura.io/
生成独立专属节点,比etherscan好用
eth_call访问合约函数
eth_call函数只用于访问不修改内存变量(view、pure)类的函数,因为eth_call的内部修改不会被广播,也不消耗Gas
访问接口
Call(&result,methodName,arg,"latest")
methodName 为“eth_call”
call()传入参数arg
type CallArg struct {From common.Address `json: "from"`To common.Address `json: "to"`Gas string `json: "gas"`GasPrice string `json: "gasPrice"`Value string `json: "value"`Data string `json: "data"`Nonce string `json: "nonce"`}
to为智能合约的地址
若出现GAS用尽的报错,将Gas值改为“0x1000000“,但并不会真的消耗gas
Data设置
data存储调用函数的信息和传入参数,分为以下2个部分:
- 调用该智能合约的函数ID
ID生成方法: 根据函数的ABI编码(从remix中复制)生成ID,如ERC20协议的balanceOf函数的ABI编码
contractABI := `[{"constant": true,"inputs": [{"name": "_owner","type": "address"}],"name": "balanceOf","outputs": [{"name": "_value","type": "uint256"}],"payable": false,"stateMutability": "view","type": "function"},{"constant": true,"inputs": [],"name": "symbol","outputs": [{"name": "","type": "string"}],"payable": false,"stateMutability": "view","type": "function"}]`methodName := "balanceOf"
生成ID:
func MakeMethodID(methodName string,abistr string)(string,error){abi := &abi2.ABI{}//生成该函数实例err := abi.UnmarshalJSON([]byte(abistr))if err != nil{return "", err}method := abi.Methods[methodName]methodIdBytes := method.IDmethodId := "0x"+common.Bytes2Hex(methodIdBytes)return methodId,nil
}
当然也可以通过remix编译合约后生成的JSON来得到函数ID,如某合约的各个ID:
"methodIdentifiers": {"allowed(address,address)": "5c658165","approve(address,uint256)": "095ea7b3","balance(address)": "e3d670d7","balanceAll()": "42729c14","balanceOf(address)": "70a08231","decimals()": "313ce567","gotCoin(address)": "3d492e56","name()": "06fdde03","symbol()": "95d89b41","totalSupply()": "18160ddd","transfer(address,address,uint256)": "beabacc8","transfer(address,uint256)": "a9059cbb"}
- 传入参数
字符串类型:
arg1 := common.HexToHash("aa").String()[2:]
地址类型:
common.HexToHash(userAddress).String()[2:]
整型:
//先传入确定真实值valueStr := "100"//真实值realValue := myTools.GetRealDecimalValue(valueStr,0)//转换为bigint类型realValueBig,_ := new(big.Int).SetString(realValue,10)//转换为以太坊所用的16进制hash类型arg := common.BytesToHash(realValueBig.Bytes()).String()[2:]
- 字符串组合
Data: methodId + arg1 + arg2,
实现以太坊交易
发送数据
参数组装后需要通过私钥签名,签名过程
types.SignTx(tx, types.HomesteadSigner{}, unlockedKey.PrivateKey)
签名后进行RLP序列化以向其他节点传入数据:
https://segmentfault.com/a/1190000011763339
解读数据
- RLP反序列化 在decode.go中
- 参数校验+签名校验 在validate.go中
- 订单池判断,能否加入订单池 在tx_pool.go中
使用eth_sendRawTransaction发起交易(以太坊版本 1.6)
eth_sendRawTransaction可以实现如下三种功能:
- ETH转账
- 部署智能合约
- 调用智能合约(修改状态变量后能广播)
调用方法如下:
err = r.client.Getrpc().Call(&txHash,methodName,common.ToHex(txRlpData))
发送一个以太坊交易需要以下流程:
- 按标准构建交易结构体
- 拥有一个keystore存储的JSON格式钱包
- 解锁钱包
- 为交易签名
- RLP序列化
- 获取发送交易地址的nonce
- 发送交易
构建交易:
transaction := types.NewTransaction(nonce.Uint64(),to,amount,gasLimit_,gasPrice_, databytes)
以太坊源码:
func NewTransaction(nonce uint64, to common.Address, amount, gasLimit, gasPrice *big.Int, data []byte) *Transaction {return newTransaction(nonce, &to, amount, gasLimit, gasPrice, data)
}
func newTransaction(nonce uint64, to *common.Address, amount, gasLimit, gasPrice *big.Int, data []byte) *Transaction {if len(data) > 0 {data = common.CopyBytes(data)}d := txdata{AccountNonce: nonce,Recipient: to,Payload: data,Amount: new(big.Int),GasLimit: new(big.Int),Price: new(big.Int),V: new(big.Int),R: new(big.Int),S: new(big.Int),}if amount != nil {d.Amount.Set(amount)}if gasLimit != nil {d.GasLimit.Set(gasLimit)}if gasPrice != nil {d.Price.Set(gasPrice)}return &Transaction{data: d}
}
交易结构体,确认数据类型:
type txdata struct {AccountNonce uint64 `json:"nonce" gencodec:"required"`Price *big.Int `json:"gasPrice" gencodec:"required"`GasLimit *big.Int `json:"gas" gencodec:"required"`Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creationAmount *big.Int `json:"value" gencodec:"required"`Payload []byte `json:"input" gencodec:"required"`// Signature valuesV *big.Int `json:"v" gencodec:"required"`R *big.Int `json:"r" gencodec:"required"`S *big.Int `json:"s" gencodec:"required"`// This is only used when marshaling to JSON.Hash *common.Hash `json:"hash" rlp:"-"`
}
注意:交易ETH时Payload为nil,调用函数时amount为0,部署合约时to为空
获取nonce
func (r *ETHERRPCRequester) GetNonce(address string)(*big.Int,error){methodName := "eth_getTransactionCount"nonce := ""err := r.client.Getrpc().Call(&nonce,methodName,address,"pending")if err != nil{return nil, err}//返回的是16进制 0x开头n,_ := new(big.Int).SetString(nonce[2:],16)return n,nil
}
序列化:
//rlp序列化
txRlpData,err := rlp.EncodeToBytes(signTx)
发送ETH或Token时需要进行换算:
//decimal为几,等于硬币最小单位到小数点后几位
func GetRealDecimalValue(value string,decimal int) string{if strings.Contains(value,"."){//存在小数arr := strings.Split(value,".")if len(arr) != 2{return ""}num := len(arr[1])left := decimal - numreturn arr[0] + arr[1] + strings.Repeat("0",left)}else {return value + strings.Repeat("0",decimal)}
}
实现监听
<<利用web.js
<Dapp实战>
(持续更新)
区块链与DApp开发(学习总结)相关推荐
- 区块链智能合约开发学习
最近正在肝区块链知识学习,入手学习智能合约的开发,由于网上资料实在是太少了,好不容易东拼西凑完成了智能合约的开发.编译.部署.web3js调用(网页页面)和web3j调用(java调用),赶紧趁热把重 ...
- 从3年前接触区块链,到开发出装机量最大客户端Geth,看看人家的职业发展之路 | 人物志...
记者 | Aholiab 出品 | 区块链大本营 Go-Ethereum,因为是用Go语言编写的,也简称为Geth.Go-Ethereum是以太坊基金会提供的官方客户端软件,也是目前使用最为广泛的客户 ...
- “区块链第一考”今天结束,史上首张“区块链技术软件开发师”证书即将发放...
记者: 史上第一张区块链考级试卷,你会做吗?给你做个题,看看会不会. 以太坊开发者创建智能合约时,需要发送一笔交易到一个地址,这个地址的开头是 A.0x B.0x1 C.0x0 D.0x00 你知道答 ...
- Solana区块链智能合约开发简要流程
Solana区块链智能合约开发简要流程 Solana区块链是当今市值第5的区块链,已经有很多知名生态准备部署在Solana上.相比于类以太坊(EVM)区块链来讲,Solana上智能合约开发(叫Prog ...
- 基于区块链交易技术开发的证券
基于区块链交易技术开发的证券 区块链交易技术在金融市场还不是主流的技术运用,但是加密货币在金融领域的影响力却不可同日而语.虽然目前的加密货币市场低迷,但是区块链技术却在全球各个国家引起了行业的重视. ...
- MMO游戏War Riders宣布将于基于区块链的游戏开发公司Immutable集成
可赚取加密货币的MMO游戏War Riders宣布,将于基于区块链的游戏开发公司Immutable集成,合作将使玩家可免Gas的铸造和交易,并扩大War Riders的用户. 文章链接:https:/ ...
- 区块链研究生专业_滁州区块链平台技术开发专业软件公司
滁州弈聪软件是专业滁州区块链技术开发公司,致力于区块链平台技术开发及区块链平台搭建服务,在电子货币,加密货币及虚拟币钱包开发,虚拟币交易系统开发,区块链+数字资产管理系统开发及电子金融行业具有丰富的经 ...
- 部署IBM区块链平台:开发区块链业务网络到Hyperledger Fabric(多个组织)
Deploying a IBM Blockchain Platform: Develop blockchain business network to Hyperledger Fabric (mult ...
- 区块链知识系列 - 系统学习EVM(二)-存储与安全
区块链知识系列 - 系统学习EVM(一) 特点 EVM出于所谓运算速度和效率方面考虑,采用了非主流的256bit整数. 不支持浮点数 缺乏标准库支持,例如字符串拼接.切割.查找等等都需要开发者自己实现 ...
最新文章
- 【ACM】与全排列相关的STL函数 prev_permutation next_permutation
- au vst插件_失真效果音频插件
- 工业用微型计算机(29)-dos和BIOS调用(3)和半导体存储器构造
- MySQL主从延时这么长,要怎么优化?
- 避免常见的6种HTML5错误用法,如何避免常见的6种HTML5错误用法
- 未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0[已解决]
- 【python】时间处理函数以及文件操作
- 腾讯225页报告:AI正取代互联网成为新引擎,马化腾提七大关键词
- 国际通用计算机编码,计算机中的编码知识
- Quartz数据库存储
- 微信小程序登录功能实现(最新)
- 如何从零开始写一个操作系统?
- 用Java实现I am a student逆序输出为student a am I,不借助split方法和StringBuffer!
- Python调用百度AI识别身份证
- python快速入门编程第5章编程题
- 风格迁移2020 —— 论文汇总——云盘分享
- MOV格式的视频应该如何转换成MP4格式的
- dedecms教程:织梦未审核文档禁止动态浏览
- C语言及程序设计 实践参考——个人所得税计算器if语句版
- C语言学习实例2-提成计算