# 学习笔记：Web3 全栈dAPP

By [Evelyn](https://paragraph.com/@qianyi) · 2023-01-14

---

### 1、Solidity基本语法 | 对象、变量、函数、事件

*   \*\*对象。\*\*账户是一个对象，它包含地址、余额、nonce、并且存储了状态和代码。账户可以是合约账户或外部账户（External Owned Account）
    
*   \*\*变量。\*\*两种变量，状态变量和内存变量。
    
    *   在合约内部、函数外部声明的变量都是状态变量；状态变量存储合约的当前值，它们存储在区块链中。
        
    *   函数内声明的变量是**内存变量。只在函数执行时可用,类比传统计算机的内存调用数据——一些函数参数的存储。内存变量**只能在函数内部执行，且仅在函数调用时可用。
        
*   **Solidity变量的数据及其存储位置**
    
    *   Storage (存储)
        
    *   Memory（内存）
        
    *   Calldata（调用参数）
        
    
    当输入一笔交易，Transaction会转换成一个Message对象，传入EVM执行。如果是一笔普通转账交易，那么直接修改`StateDB`中对应的账户余额即可。如果是智能合约的创建或者调用，则需要通过EVM中的解释器（interperter）加载和执行字节码，执行过程中可能会查询或者修改StateDB。
    
    **让我们来仔细观察这张图片：**
    
    EVM内部分为：EVM World stateDB；Interpreter解释器、
    

![](https://storage.googleapis.com/papyrus_images/0bb614ddadb2625ce54a415dd56b80557b7c9e1a34ba64aafeb2440939cf1229.png)

EVM World State，系统状态就是以太坊整个网络中所有账户的状态，它是一个merkle patricia trie结构：

![](https://storage.googleapis.com/papyrus_images/459df422ae30ae8b5ba2ee0192e4bd7dc3d6ac35b1e24bfd2da0adb89cb3615d.jpg)

*   \*\*函数。\*\*函数机制是为了从【状态变量】读取值和向【状态变量】写入值；
    
*   **事件**（event） 事件是从合约中触发的，任何对它们感兴趣的人都可以捕获它们并响应执行代码。合约中声明的事件在全域内有效，并且被合约中的函数所调用。使用**event**关键字声明一个事件，后跟一个标识符和参数列表并以分号结尾；
    
*   限定符。去修饰【变量】与【函数】，比如：
    

    //^1.1.1         表示指定主版本号下所有更新的版本，如1.2.2，不匹配2.0.1
    // >=            表示大于等于该版本号
    //1.0.0-2.0.0    表示版本号在这个范围之间的版本号（包含两端）
    
    //public         公有的，任何人可以调用
    //private        私有，只能在声明的合约内部调用
    //external       仅合约外部可以调用，合约内部需要使用this来调用
    //view/constant  函数会读取但是不会修改任何状态
    //pure           函数不使用任何状态变量  
    //internal       默认情况下，如果没有指定任何内容，则【状态变量】具有internal限定符。意味这个变量只能在当前的【合约函数】内部和任何继承它们的合约中使用。这些变量不能被外部访问修改，但是可以查看。
    ......
    
    
    pragma solidity ^0.1.1 
    contract XXX {
          string say="hello world！"
    } 
    

### 2、编译过程：用编译器将指令转换为字节码

*   在Remix或者ChainIDE上写代码，会自动匹配相应的编译器
    
*   编译（Compiling）是将高级编程语言（如Solidity）编写的代码转换为较低级语言（如以太坊虚拟机字节码）；
    

**部署：部署合约（合约ABI+合约字节码）到EVM虚拟机上**

*   ABI，Application Binary Interface：应用程序二进制接口，即合约的接口说明。合约代码被编译后,它对应的ABI也就确定了。
    
*   字节码是为虚拟机的高效执行而设计的抽象指令集。以数字格式表示，人类不可读。虚拟机上执行的是字节码Bytecode。
    
*   EVM，Ethereum Virtual Machine，以太坊虚拟机，是基于栈的虚拟机，用于执行字节码。在以太坊中，其执行模型指定了在给定一系列字节码指令和一小组环境数据的情况下如何改变系统状态。
    

### 3、Gas、Gas Limit和Gas Price

*   Gas收费：其中一个字，有32个字节，每个字节8位，一个字有256位。gas price单位是Gwei；每占用一个字节，消耗Gas limit；执行过程中的gas limit，即为运行过程中操作所占用的字节消耗的算力。
    
*   每笔交易都被要求包括一个**gas limit**（也可被称为startGas）和一个愿为每个gas支付的单位价格。Tx**交易费 = gas Used （该交易消耗的总gas数量**）\* gasPrice（**该交易中单位gas的价格**）。矿工可以有选择的打包这些交易并收取这些费用。
    
*   单个交易的**gas limit**值，代表了这个交易的执行最多被允许使用的gas数量。
    
    *   如果实际需要使用的gas数量（gas used）≤ gas limit，那么这个交易会被处理，且根据交易字节长度计算实际花费，从gas limit里面扣除gas used给矿工，剩余gas退还给发起交易者。反之，如果gas used＞gas limit，则交易失败且所有操作被复原，交易费全部被矿工收取。
        
*   **gas price**的计量单位为gwei，1 gwei = 10^9 wei = 10^(-9) ETH）由交易发起人设定，以争取尽早被矿工打包。
    
*   **区块gas limit**是**单个区块**允许的最多gas总量。假设有5笔交易的gas limit分别是10、20、30、40和50.如果区块gas limit是100，那么前4笔交易就能被成功打包进入这个区块。矿工有权决定将哪些交易打包入区块。目前区块的gas limit是 [4,712,357 gas，数据来自于ethstats.net](https://ethstats.net/)，这表示着大约224笔转账交易（gas limit为21000）可以被塞进一个区块（区块时间大约在15-20秒间波动）。
    

### 4、Web2&Web3的交互界面：Alchemy

[https://docs.alchemy.com/alchemy/](https://docs.alchemy.com/alchemy/)

Alchemy 是一个 Web3 开发者平台，专注于简化区块链开发。构建了一套开发人员工具、API集和卓越的节点基础设施，以无缝构建和运行区块链应用程序。

API集合包括enhanced API和chain API；Ethereum API 允许【应用程序】连接到作为以太坊区块链一部分的【以太坊节点】。开发人员可以利用 API 提供的endpoints与链上数据交互，并将不同类型的交易发送到网络。API 遵循 JSON-RPC 标准。JSON-RPC 是一种无状态、轻量级的远程过程调用 (RPC) 协议，通常在与以太坊交互时使用。

使用方法：申请一个 API 密钥；并且得到一串URL

    const axios=require（"axios"）
    
    const data={
          "jsonrpc":"2.0"
          "method":"eth_blockNumber",
          "params":[],
          "id":0
    }
    
    const config={
          method:"post"
          url:"https//eth-mainnet.ALCHEM",
          Headers:{
              "Content-Type":"application/json"
          }
          data：data
    }

---

*Originally published on [Evelyn](https://paragraph.com/@qianyi/web3-dapp)*
