FxAjax ChainNews:
geth 源码一直在不断增加,优化,发展到现在已经非常庞大,对于初次学习 geth 源码,整体认识 geth 还是有一定的意义。而阅读代码可以加深理解以太坊的模块组成,揣测设计的想法和思路。本篇文章带你学习 geth 源码。
来源 | kari_zhang 博客 作者 | kari_zhang
背景geth 源码一直在不断增加,优化,发展到现在已经非常庞大,第一次看 geth 源码,会有不小的难度。虽然如此,还是可以从 geth 仓库的第一个 commit 开始,这时的代码比较少,但是以太坊核心的雏形已经隐隐可见,阅读代码可以加深理解以太坊的模块组成,揣测设计的想法和思路。
项目结构去掉单元测试文件,整个项目只有 big.go vm.go parsing.go transaction.go block.go block_manager.go ethereum.go serialization.go 8 个文件。这 8 个文件都比较小,功能比较简单,也很好理解。
数学计算big.go 封装了大整数的指数运输。
虚拟机vm.go 定义了虚拟机操作码 , 操作码类型 , 虚拟机结构和虚拟机的实现。
虚拟机内部定义的指令码有:
oSTOP int = 0x00oADD int = 0x10oSUB int = 0x11oMUL int = 0x12oDIV int = 0x13oSDIV int = 0x14oMOD int = 0x15oSMOD int = 0x16oEXP int = 0x17oNEG int = 0x18oLT int = 0x20oLE int = 0x21oGT int = 0x22oGE int = 0x23oEQ int = 0x24oNOT int = 0x25oSHA256 int = 0x30oRIPEMD160 int = 0x31oECMUL int = 0x32oECADD int = 0x33oSIGN int = 0x34oRECOVER int = 0x35oCOPY int = 0x40oST int = 0x41oLD int = 0x42oSET int = 0x43oJMP int = 0x50oJMPI int = 0x51oIND int = 0x52oEXTRO int = 0x60oBALANCE int = 0x61oMKTX int = 0x70oDATA int = 0x80oDATAN int = 0x81oMYADDRESS int = 0x90oSUICIDE int = 0xff
总共 36 个指令码,细心的读者可能会发现指令码定义的值不是连续的,是跳跃的,通过通读代码分析,原因是指令码值的高位是记录指令类型。
vm 的实现是基于栈的,实现相对比较简单。
大部分指令码的功能没有实现,只实现了以下指令码的功能 oSTOP oADD oSUB oMUL oDIV oSET oLD oLT oJMP oJMPI
智能合约编译parsing.go 主要实现的是智能合约的编译和对编译后的代码进行处理,后续供 vm 执行。
交易transaction.go 定义了交易的结构,还有费用和收益变量。一笔交易包括发起者,接受者,交易的数量,交易的费用,编译后的脚本源码, 运行需要内存,交易签名 和 地址。
费用和收益变量只有初始化赋值,没有具体使用。
脚本源码是智能合约的雏形,为了方便描述和理解还是称呼它为智能合约。此时的智能合约语言和 x86 intel 汇编类似, 语法比较简单,一个操作指令加上操作数,操作数的个数最常见是 0 个,1 个,2 个和 3 个,设计者实现的时候,最多可以支持 6 个。
操作指令和操作数之间用空格分开,操作数与操作数之间也用空格分开。
定义的操作指令有以下这些:(记作 映射表 1)
"STOP": "0", "ADD": "16", // 0x10 "SUB": "17", // 0x11 "MUL": "18", // 0x12 "DIV": "19", // 0x13 "SDIV": "20", // 0x14 "MOD": "21", // 0x15 "SMOD": "22", // 0x16 "EXP": "23", // 0x17 "NEG": "24", // 0x18 "LT": "32", // 0x20 "LE": "33", // 0x21 "GT": "34", // 0x22 "GE": "35", // 0x23 "EQ": "36", // 0x24 "NOT": "37", // 0x25 "SHA256": "48", // 0x30 "RIPEMD160": "49", // 0x31 "ECMUL": "50", // 0x32 "ECADD": "51", // 0x33 "SIGN": "52", // 0x34 "RECOVER": "53", // 0x35 "COPY": "64", // 0x40 "ST": "65", // 0x41 "LD": "66", // 0x42 "SET": "67", // 0x43 "JMP": "80", // 0x50 "JMPI": "81", // 0x51 "IND": "82", // 0x52 "EXTRO": "96", // 0x60 "BALANCE": "97", // 0x61 "MKTX": "112", // 0x70 "DATA": "128", // 0x80 "DATAN": "129", // 0x81 "MYADDRESS": "144", // 0x90 "BLKHASH": "145", // 0x91 "COINBASE": "146", // 0x92 "SUICIDE": "255", // 0xff
可以看出这是操作指令到虚拟机内部指令码的映射。
编译规则很简单:
1. 操作指令根据映射表 1\, 得到 vm 的内部指令码。 2. 每一个操作数(第 i 个操作数,i 记作位置序数, 从 1 开始)分别乘以 256 的 i 次方, 3. 将步骤 2 的乘积依次相加,最后加上步骤 1 得到的指令, 最终的和作为编译结果。
一个合法的智能合约源码片段可能是这样(记作 代码片段 1)
"SET 10 6", "LD 10 10",
按照编译规则,代码片段 1 最终的编译结果是这样的
395843 // 67 + 10 * 256 + 6 * 256^2133698 // 66 + 10 * 256 + 10 * 256^2
vm 运行时,根据编译规则的逆规则,解析出指令码和操作数,根据指令码的功能,进行下一步处理。
运行需要内存没有使用,猜测是用作运行智能合约。
签名字段没有使用,猜测是校验交易是否篡改过。
地址是对 transaction 结构序列化后的字节数组取 sha256 的前 20 位。
区块block.go 用来定义块结构,非常简单,仅包含一个 transaction 数组 .
区块管理器block_manager.go 是定义块管理器,用来处理块,持有一个 vm 指针,依次执行块里面的每一个交易的智能合约。
以太坊入口ethereum.go 是 demo 程序入口, mock 两笔交易,打印 vm 执行的日志,最后打印了其中一笔交易的序列化结果。
交易序列化serialization.go 实现序列化功能,采用的是 RLP 编码,只能对字符串编码。编码规则是
1. 如果是字符串,编码结果是”\x00” 加上字符串的长度,再加上原字符串。计算字符串的长度有一个规则,确保编码无二义性,能正确解码。 2. 如果是字符串数组,编码结果是”\x01”加上每一个字符串编码结果的长度和的编码,再加上每一个字符串的编码结果。有点绕口,这是个递归的过程。 3. 如果是其他类型需要转换成字符串或者字符串数组。 RLP 编码的规律是以数据类型开始,字符串是”\x00”, 字符串数组是”\x01, 然后是数据长度,最后是数据内容。 RLP 编码和解码是递归过程,实现比较简单,编码紧凑,传输效率较高,后续版本中,在网络传输和本地存储都有 RLP 编码的影子。
总结总体来说,这个版本的代码比较简单,是 geth 的初始设计和验证,没有实现太多的功能,比喻账号,P2P 网络,共识算法等都没有实现,区块链,编译器和虚拟机也设计比较简单,与正式发布版差异比较大,不过对于初次学习 geth 源码,整体认识 geth 还是有一定的意义。
更多精彩内容,关注FxAjax ChainNews 公众号(id:chainnewscom),或者来微博 @ FxAjax ChainNews 与我们互动!转载请注明版权和原文链接!
来源链接:blog.csdn.net
21Shares携手法国兴业银行,强化德国及东欧市场加密ETP流动性
CME集团6月30日推出现货报价期货:比特币、以太坊及标普500等长达5年持有
eToro推出加密资产转账与兑现功能:比特币、以太坊可无缝投资多资产
nxtAssets GmbH携手SIX推出比特币与以太坊ETP:加密资产交易总数达398
Clearstream携手Crypto Finance推出加密资产托管服务,德意志交易所集团引领机构投资者新风潮
西班牙BBVA获批推出比特币和以太坊交易服务,零售客户可通过手机银行直接管理加密资产
Bybit遭遇重大黑客攻击,15亿美元数字货币被盗
Bybit遭遇安全漏洞,1.4亿美元以太坊代币被盗,市场反应激烈
Bybit交易所遭黑客攻击,14亿美元ETH被盗,资金安全隐患引发行业关注
以太坊 ETF 在美国上市首日交易量达 10 亿美元,占比特币交易量的 23%
现货以太 ETF 将于今日在 SEC 最终批准后开始交易
芝商所推出以微欧元计价的比特币和以太坊期货
Visa (NYSE:V) 設想在以太坊網絡上進行自動支付
俄罗斯银行建议对NFT、智能合约进行监管
MetaMask“Portfolio Dapp”新增跨链桥服务
0xScope:Alameda以太坊上627个地址总资产约1亿美元
Paradigm:BTC和ETH看跌期权的需求重新出现
Horizen Labs公布ApeCoin DAO质押系统界面
Avalanche基金会为交易平台GMX推出400万美元奖励计划
Chainlink与MVGX合作探索加密碳交易



