技术

DApp 技术概览

下面开始都是我的理解哈,如果有问题及时指正。 DApp 开发就是 开发智能合约 和 与智能合约交互。 智能合约

奶爸 · 69 min read >

下面开始都是我的理解哈,如果有问题及时指正。

DApp 开发就是 开发智能合约与智能合约交互

智能合约

概述

就像是 AWS Lambda,以链为数据库,运行在以太坊节点上面的一段代码。下面是一个简单的 Solidity 的具有读写接口的例子:

pragma solidity >=0.4.0 <0.7.0;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

调用 set 接口就会把 x 储存到合约的 storedData 里面,这个操作会被所有的以太坊节点验证(也是一个执行过程),验证通过后这个 x 就储存到了每一个以太坊节点上,然后调用 get 接口的话会读取到之前 set 的值,Solidity 只是智能合约语言中的一种,其他还有:

  • Vyper:Python 语法的智能合约语言。

可以在以太坊官方开发工具 Remix 中实际操作实践一下,使用 JavaScript VM 不需要安装钱包环境。如果觉得还不够,可以选择测试网 Kovan、Ropsten 进行实际的智能合约实践。

一个 Transcation 的生命周期

  1. 首先有一个钱包环境 MetaMask、imToken
  2. 调用只能合约的方法
  3. 由 Web3 将你的操作进行打包
  4. 交由钱包签名
    1. 通过钱包连接的节点预估本次交易的 Gas 费用,在这里如果评估失败,钱包会直接报错,无需签名。
    2. 获取当前网络状态,评估 GasPrice
  5. 钱包通过连接的节点广播交易
  6. 钱包连接的节点第一个进行验证,验证通过后广播给维护的其他节点
  7. 等待矿工打包到新区块中
  8. 交易成功,合约状态变更(相当于修改数据库)。如果交易不成功,所有状态回滚。无需考虑并发。

与外部交互

智能合约与外部交互的方式只有一种:Event。通过智能合约发出的 Event,我们的订阅者可以知道合约内部发生了什么,比如 用户注册,一个钱包在智能合约中注册成为用户,其他的人就需要监听这个合约发出的 Event,来得知是哪个钱包地址注册成为用户。

Tools

  • IDE:Remix(推荐,使用 Solidity 写单元测试最好)、VSCode
  • 脚手架:Truffle、OpenZeppelin SDK

Ref

  • OpenZeppelin:OpenZeppelin provides tools to write, deploy and operate decentralized applications.
  • 区块链技术博客:区块链相关技术博客,专注基于以太坊的区块链技术,Solidity编程语言,Truffle框架,web3.js。
  • 深入浅出区块链:深入浅出区块链是由一群区块链技术爱好者共同维护的一个秉承去中心化精神的区块链技术博客。

与智能合约交互

我把 JavaScript@web3.js、Dart@web3dart、Golang@go-ethereum 等 WebApp、MobileApp、后端服务的 DApp 开发统称为 与智能合约交互,因为 DApp 开发的本质就是与智能合约交互。不论是 JavaScript、Dart、Goalng 都是与以太坊节点的 WebSocket、HTTP、gRPC 接口进行交互,没有本质区别。

DApp –> 智能合约

以 JavaScript 为例演示一下如何与智能合约交互交互的:

// 首先你需要有一个 Web3 实例
var web3 = new Web3(Web3.givenProvider || "ws://localhost:8546");
// 通过智能合约的 ABI 代码和合约地址初始化 智能合约 实例
const simpleStorage = web3.eth.Contract(
  JSON.parse(simpleStorageABIString),
  simpleStorageAddress
);
// 调用智能合约 set 方法在链上储存一个值
simpleStorage.methods.set(123).send({from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'})
  .on('transactionHash', function(hash){
      ...
  })
  .on('confirmation', function(confirmationNumber, receipt){
      ...
  })
  .on('receipt', function(receipt){
      console.log('已将 storedData 设置为 123')
  })
	.on('error', console.error);
// 调用 get 方法读取 storedData 的值
simpleStorage.methods.get().call()
	.then(console.log); // 123

Golang 的交互方式也是大同小异,不过 Golang 可以通过 ABI 使用 codegen 生成基础代码。如果理解了一个其他的也都可以举一反三了。

智能合约 –> DApp

在执行合约代码的 EVM 中没有网络请求的功能也不能进行网络请求。我们需要通过智能合约发出的 Event 来知道智能合约中的数据变更。

下面通过 Golang 的一个例子来解释一下:

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/ethereum/go-ethereum"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/ethclient"
)

func main() {
    // 首先连接以太坊节点,相当于有了 JavaScript 的钱包环境
    client, err := ethclient.Dial("wss://rinkeby.infura.io/ws")
    if err != nil {
        log.Fatal(err)
    }

  	// 要监听Event的 智能合约 地址
    contractAddress := common.HexToAddress("0x147B8eb97fD247D06C4006D269c90C1908Fb5D54")
    query := ethereum.FilterQuery{
        Addresses: []common.Address{contractAddress},
    }

  	// 通过客户端进行监听
    logs := make(chan types.Log)
    sub, err := client.SubscribeFilterLogs(context.Background(), query, logs)
    if err != nil {
        log.Fatal(err)
    }

  	// 处理监听到的 Event
    for {
        select {
        case err := <-sub.Err():
            log.Fatal(err)
        case vLog := <-logs:
          	// 可以把 Event 中的数据提取出来,对应处理
            fmt.Println(vLog) // pointer to event log
        }
    }
}

注意 JavaScript 也可以监听 Event,在设计产品的时候着重考虑哪些需要在外部数据库中持久储存用于日后的分析。大部分的操作都可以直接与链交互,需要用心规划外部服务与链接口的平衡。

Ref

  • 用 Go 来做以太坊开发:这本迷你书的本意是给任何想用Go进行以太坊开发的同学一个概括的介绍。
  • Drizzle:A collection of front-end libraries that make writing dapp user interfaces easier and more predictable。社区中有很多成熟的解决方案,有些时候多搜一搜,事半功倍。
  • Ethereum Developer Tools List:A guide to available tools, components, patterns, and platforms for developing applications on Ethereum.

其他

  • 有很多的坑需要踩,尤其是兼容性的问题,有些 Web3 的特性在手机上面不工作,但是在 PC 上面就工作良好,比如钱包签名。
  • 每个手机端钱包——都不一样!对前端的要求比较高。
  • 对后端来说,将 Event 处理之后都是 CRUD 的活,不需要担心。
  • 其他有意思的东西
    • 以太坊真是不行,如果想自己做公链的话下面有两个选择:
      • Substrate: The platform for blockchain innovators
      • cosmos-sdk:A Framework for Building High Value Public Blockchains
    • Polkadot: Decentralized Web 3.0 Blockchain Interoperability Platform。跨链融合,下一代大一统技术。
  • 重复一遍:在设计产品的时候着重考虑哪些需要在外部数据库中持久储存用于日后的分析。大部分的操作都可以直接与链交互,需要用心规划外部服务与链接口的平衡。

奶爸
啦啦啦,啦啦啦 主页

为什么我不喜欢NodeJS

奶爸 @ 技术
  ·   3 min read

发表评论

电子邮件地址不会被公开。 必填项已用*标注