从命令行开始解析生成创世块源码

使用NodeJs、Express开发区块链 本篇文章主要讲述了,加密货币的一些特征,以及node.js的基础,服务启动如何与链进行交互,以及node.js在区块链技术领域的调查描述,并进行了案例示范,其次对源码进行解读。从架构设计的角度,层层剖析区块链的设计原理,深刻解读相关概念和技术。从项目设计的角度谋篇,从项目入口程序出发,介绍了本项目的整体结构,分别介绍了P2P网络、区块链、共识机制等区块链核心内容及其代码实现。 从本书来说,首先了解... 阅读详情

创建创世块的代码解析

在cmd的geth目录下的main.go中

init函数先于main函数执行,做命令的初始化,其中比较重要的有三个地方,app.Action=geth,app.Commands中consoleCommand,以及App.Before指向的匿名函数

func init() {
	// Initialize the CLI app and start Geth
	app.Action = geth
	app.HideVersion = true // we have a command to print the version
	app.Copyright = "Copyright 2013-2018 The go-ethereum Authors"
	app.Commands = []cli.Command{
		// See chaincmd.go:
		initCommand,
		importCommand,
		exportCommand,
		importPreimagesCommand,
		exportPreimagesCommand,
		copydbCommand,
		removedbCommand,
		dumpCommand,
		// See monitorcmd.go:
		monitorCommand,
		// See accountcmd.go:
		accountCommand,
		walletCommand,
		// See consolecmd.go:
		consoleCommand,
		attachCommand,
		javascriptCommand,
		// See misccmd.go:
		makecacheCommand,
		makedagCommand,
		versionCommand,
		bugCommand,
		licenseCommand,
		// See config.go
		dumpConfigCommand,
	}
	sort.Sort(cli.CommandsByName(app.Commands))

	app.Flags = append(app.Flags, nodeFlags...)
	app.Flags = append(app.Flags, rpcFlags...)
	app.Flags = append(app.Flags, consoleFlags...)
	app.Flags = append(app.Flags, debug.Flags...)
	app.Flags = append(app.Flags, whisperFlags...)

	app.Before = func(ctx *cli.Context) error {
		runtime.GOMAXPROCS(runtime.NumCPU())
		if err := debug.Setup(ctx); err != nil {
			return err
		}
		// Start system runtime metrics collection
		go metrics.CollectProcessMetrics(3 * time.Second)

		utils.SetupNetwork(ctx)
		return nil
	}

	app.After = func(ctx *cli.Context) error {
		debug.Exit()
		console.Stdin.Close() // Resets terminal mode.
		return nil
	}
}

main函数中的内容比较简单,这里不多做任何解释。

func main() {
	if err := app.Run(os.Args); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

通过gopkg.in/urfave/cli.v1包中的代码来衔接到cmd/geth/chaincmd包中的代码,APP包中中HandleAction函数action的类型是「func(*Context) error」,此时将执行a(context)方法,那么此时调用那个Action呢,就是我们前面提到的App.init()初始化命令时的initCommand,接下来我们来看看cmd/geth/chaincmd中的initCommand:

var (
	initCommand = cli.Command{
		Action:    utils.MigrateFlags(initGenesis),
		Name:      "init",
		Usage:     "Bootstrap and initialize a new genesis block",
		ArgsUsage: "<genesisPath>",
		Flags: []cli.Flag{
			utils.DataDirFlag,
			utils.LightModeFlag,
		},
		Category: "BLOCKCHAIN COMMANDS",
		Description: `
The init command initializes a new genesis block and definition for the network.
This is a destructive action and changes the network in which you will be
participating.

It expects the genesis file as argument.`,
	}	

这允许使用现有的配置功能。当所有标志被迁移时,该功能可以被删除,并且必须改变现有的配置功能,即使用本地标志

func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error {
	return func(ctx *cli.Context) error {
		for _, name := range ctx.FlagNames() {
			if ctx.IsSet(name) {
				ctx.GlobalSet(name, ctx.String(name))
			}
		}
		return action(ctx)
	}
}

根据给定的JSon格式文件初始化创世块

func initGenesis(ctx *cli.Context) error {
	// Make sure we have a valid genesis JSON
	genesisPath := ctx.Args().First()
	if len(genesisPath) == 0 {
		utils.Fatalf("Must supply path to genesis JSON file")
	}
	file, err := os.Open(genesisPath)
	if err != nil {
		utils.Fatalf("Failed to read genesis file: %v", err)
	}
	defer file.Close()

	genesis := new(core.Genesis)
	if err := json.NewDecoder(file).Decode(genesis); err != nil {
		utils.Fatalf("invalid genesis file: %v", err)
	}
	// Open an initialise both full and light databases
	stack := makeFullNode(ctx)
	for _, name := range []string{"chaindata", "lightchaindata"} {
		chaindb, err := stack.OpenDatabase(name, 0, 0)
		if err != nil {
			utils.Fatalf("Failed to open database: %v", err)
		}
		_, hash, err := core.SetupGenesisBlock(chaindb, genesis)
		if err != nil {
			utils.Fatalf("Failed to write genesis block: %v", err)
		}
		log.Info("Successfully wrote genesis state", "database", name, "hash", hash)
	}
	return nil
}

将初始创世块存储

chaindb, err := stack.OpenDatabase(name, 0, 0)
		if err != nil {
			utils.Fatalf("Failed to open database: %v", err)
		}

涉及到的Core层次的代码

genesis := new(core.Genesis)

_, hash, err := core.SetupGenesisBlock(chaindb, genesis)
	if err != nil {
		utils.Fatalf("Failed to write genesis block: %v", err)
	}

创世块的数据结构

type Genesis struct {
	Config     *params.ChainConfig `json:"config"`
	Nonce      uint64              `json:"nonce"`
	Timestamp  uint64              `json:"timestamp"`
	ExtraData  []byte              `json:"extraData"`
	GasLimit   uint64              `json:"gasLimit"   gencodec:"required"`
	Difficulty *big.Int            `json:"difficulty" gencodec:"required"`
	Mixhash    common.Hash         `json:"mixHash"`
	Coinbase   common.Address      `json:"coinbase"`
	Alloc      GenesisAlloc        `json:"alloc"      gencodec:"required"`

	// These fields are used for consensus tests. Please don't use them
	// in actual genesis blocks.
	Number     uint64      `json:"number"`
	GasUsed    uint64      `json:"gasUsed"`
	ParentHash common.Hash `json:"parentHash"`
}

检查创世块的相关处理逻辑,符合逻辑写创世块,或者反馈控制台相应的问题

func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
	if genesis != nil && genesis.Config == nil {
		return params.AllProtocolChanges, common.Hash{}, errGenesisNoConfig
	}

	// Just commit the new block if there is no stored genesis block.
	stored := GetCanonicalHash(db, 0) //获取genesis对应的区块
	if (stored == common.Hash{}) { //如果没有区块 最开始启动geth会进入这里。
		if genesis == nil { 
			//如果genesis是nil 而且stored也是nil 那么使用主网络
			// 如果是test  dev  rinkeby 那么genesis不为空 会设置为各自的genesis
			log.Info("Writing default main-net genesis block")
			genesis = DefaultGenesisBlock()
		} else { // 否则使用配置的区块
			log.Info("Writing custom genesis block")
		}
		// 写入数据库
		block, err := genesis.Commit(db)
		return genesis.Config, block.Hash(), err
	}

	// Check whether the genesis block is already written.
	if genesis != nil { //如果genesis存在而且区块也存在 那么对比这两个区块是否相同
		block, _ := genesis.ToBlock()
		hash := block.Hash()
		if hash != stored {
			return genesis.Config, block.Hash(), &GenesisMismatchError{stored, hash}
		}
	}

	// Get the existing chain configuration.
	// 获取当前存在的区块链的genesis配置
	newcfg := genesis.configOrDefault(stored)
	// 获取当前的区块链的配置
	storedcfg, err := GetChainConfig(db, stored)
	if err != nil {
		if err == ErrChainConfigNotFound {
			// This case happens if a genesis write was interrupted.
			log.Warn("Found genesis block without chain config")
			err = WriteChainConfig(db, stored, newcfg)
		}
		return newcfg, stored, err
	}
	// Special case: don't change the existing config of a non-mainnet chain if no new
	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
	// if we just continued here.
	// 特殊情况:如果没有提供新的配置,请不要更改非主网链的现有配置。 
	// 如果我们继续这里,这些链会得到AllProtocolChanges(和compat错误)。
	if genesis == nil && stored != params.MainnetGenesisHash {
		return storedcfg, stored, nil   // 如果是私有链接会从这里退出。
	}

	// Check config compatibility and write the config. Compatibility errors
	// are returned to the caller unless we're already at block zero.
	// 检查配置的兼容性,除非我们在区块0,否则返回兼容性错误.
	height := GetBlockNumber(db, GetHeadHeaderHash(db))
	if height == missingNumber {
		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
	}
	compatErr := storedcfg.CheckCompatible(newcfg, height)
	// 如果区块已经写入数据了,那么就不能更改genesis配置了
	if compatErr != nil && height != 0 && compatErr.RewindTo != 0 {
		return newcfg, stored, compatErr
	}
	// 如果是主网络会从这里退出。
	return newcfg, stored, WriteChainConfig(db, stored, newcfg)
}

ToBlock, 这个方法使用genesis的数据,使用基于内存的数据库,然后创建了一个block并返回。

// ToBlock creates the block and state of a genesis specification.
func (g *Genesis) ToBlock() (*types.Block, *state.StateDB) {
	db, _ := ethdb.NewMemDatabase()
	statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
	for addr, account := range g.Alloc {
		statedb.AddBalance(addr, account.Balance)
		statedb.SetCode(addr, account.Code)
		statedb.SetNonce(addr, account.Nonce)
		for key, value := range account.Storage {
			statedb.SetState(addr, key, value)
		}
	}
	root := statedb.IntermediateRoot(false)
	head := &types.Header{
		Number:     new(big.Int).SetUint64(g.Number),
		Nonce:      types.EncodeNonce(g.Nonce),
		Time:       new(big.Int).SetUint64(g.Timestamp),
		ParentHash: g.ParentHash,
		Extra:      g.ExtraData,
		GasLimit:   new(big.Int).SetUint64(g.GasLimit),
		GasUsed:    new(big.Int).SetUint64(g.GasUsed),
		Difficulty: g.Difficulty,
		MixDigest:  g.Mixhash,
		Coinbase:   g.Coinbase,
		Root:       root,
	}
	if g.GasLimit == 0 {
		head.GasLimit = params.GenesisGasLimit
	}
	if g.Difficulty == nil {
		head.Difficulty = params.GenesisDifficulty
	}
	return types.NewBlock(head, nil, nil, nil), statedb
}

Commit方法和MustCommit方法, Commit方法把给定的genesis的block和state写入数据库, 这个block被认为是规范的区块链头。

// Commit writes the block and state of a genesis specification to the database.
// The block is committed as the canonical head block.
func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
	block, statedb := g.ToBlock()
	if block.Number().Sign() != 0 {
		return nil, fmt.Errorf("can't commit genesis block with number > 0")
	}
	if _, err := statedb.CommitTo(db, false); err != nil {
		return nil, fmt.Errorf("cannot write state: %v", err)
	}
	// 写入总难度
	if err := WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty); err != nil {
		return nil, err
	}
	// 写入区块
	if err := WriteBlock(db, block); err != nil {
		return nil, err
	}
	// 写入区块收据
	if err := WriteBlockReceipts(db, block.Hash(), block.NumberU64(), nil); err != nil {
		return nil, err
	}
	// 写入   headerPrefix + num (uint64 big endian) + numSuffix -> hash
	if err := WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
		return nil, err
	}
	// 写入  "LastBlock" -> hash
	if err := WriteHeadBlockHash(db, block.Hash()); err != nil {
		return nil, err
	}
	// 写入 "LastHeader" -> hash
	if err := WriteHeadHeaderHash(db, block.Hash()); err != nil {
		return nil, err
	}
	config := g.Config
	if config == nil {
		config = params.AllProtocolChanges
	}
	// 写入 ethereum-config-hash -> config
	return block, WriteChainConfig(db, block.Hash(), config)
}

// MustCommit writes the genesis block and state to db, panicking on error.
// The block is committed as the canonical head block.
func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
	block, err := g.Commit(db)
	if err != nil {
		panic(err)
	}
	return block
}

返回各种模式的默认Genesis

// DefaultGenesisBlock returns the Ethereum main net genesis block.
func DefaultGenesisBlock() *Genesis {
	return &Genesis{
		Config:     params.MainnetChainConfig,
		Nonce:      66,
		ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
		GasLimit:   5000,
		Difficulty: big.NewInt(17179869184),
		Alloc:      decodePrealloc(mainnetAllocData),
	}
}

// DefaultTestnetGenesisBlock returns the Ropsten network genesis block.
func DefaultTestnetGenesisBlock() *Genesis {
	return &Genesis{
		Config:     params.TestnetChainConfig,
		Nonce:      66,
		ExtraData:  hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"),
		GasLimit:   16777216,
		Difficulty: big.NewInt(1048576),
		Alloc:      decodePrealloc(testnetAllocData),
	}
}

// DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block.
func DefaultRinkebyGenesisBlock() *Genesis {
	return &Genesis{
		Config:     params.RinkebyChainConfig,
		Timestamp:  1492009146,
		ExtraData:  hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
		GasLimit:   4700000,
		Difficulty: big.NewInt(1),
		Alloc:      decodePrealloc(rinkebyAllocData),
	}
}

// DevGenesisBlock returns the 'geth --dev' genesis block.
func DevGenesisBlock() *Genesis {
	return &Genesis{
		Config:     params.AllProtocolChanges,
		Nonce:      42,
		GasLimit:   4712388,
		Difficulty: big.NewInt(131072),
		Alloc:      decodePrealloc(devAllocData),
	}
}

GitHub地址:

https://github.com/guoshijiang/go-ethereum-code-analysis
关注问我技术公众号,加小问,拉您入技术交流群:
在这里插入图片描述

geth配置中,genesis.json的几个问题 现有网上流传的绝大部分 genesis.json,不适用于geth v1.6 版本。有些会导致初始化失败,有些看似初始化成功,但是后续会出各种莫名其妙的问题。本文给出genesis.json的正确配置。 阅读详情

相关推荐

创世记

创世记

解决geth配置时遇到问题 Fatal: Failed to read genesis file: open genesis.json: permission denied

Fatal: failed to write genesis block: genesis has no chain configuration :这个错误信息,就是说,你的json文件中,缺少config部分。Fatal: invalid genesis file: hex string has odd length: 从v1.6开始,设置的十六进制数值,不能是奇数位, 比如不能是0x0,而应该是0x00。这个问题应为,所查看的教程中并没有前置的客户端节点配置命令。猜测是geth版本问题,尝试更新。

m0_73379721的博客 1509

华为云Stack交付实战:从工勘到上线的全流程拆解

本文详细拆解华为云Stack交付全流程,从项目启动、工勘、LLD设计到硬件部署和软件安装,提供实战技巧与避坑指南。重点解析华为云Stack交付流程中的关键环节,如标准化工具使用、规范化文档管理和流程化协作,帮助团队高效完成从工勘到上线的复杂项目交付。

weixin_29243063的博客 156

geth的安装和使用

windows下安装Geth 1.下载地址: https://geth.ethereum.org/downloads/ 下载windows版 2.按指示安装 3.在cmd下进入安装路径,输入geth help查看是否安装成功 出现下面情况表示安装成功。 配置和使用 搭建私有网络 1.配置genesis.json文件 在geth安装目录下配置一份genesis.json文件 { "config": { "chainId": 10,

weixin_43946212的博客 4938

告别Keil4!手把手教你用Keil C51 V9.61编译51单片机代码(附最新激活方法)

本文详细介绍了Keil C51 V9.61在51单片机开发中的全栈升级指南,包括编译速度提升、调试器性能优化和现代开发支持等核心优势。通过智能安装方案、项目迁移实战和新特性深度应用,帮助开发者告别Keil4,大幅提升开发效率。附有最新激活方法和实用技巧,适用于嵌入式开发工程师。

weixin_26886855的博客 420

Design Compiler时序约束实战:如何用set_clock_uncertainty解决时钟抖动问题?

本文深入探讨了在Design Compiler时序约束实战中,如何精准运用set_clock_uncertainty命令解决时钟抖动等非理想性问题。文章详细解析了该命令在时钟树综合前后的不同应用策略、建立时间与保持时间的差异化设置,并对比了其与set_clock_jitter的适用场景,旨在帮助数字IC设计工程师制定稳健的时序约束,为后端物理实现预留合理的安全裕量,从而高效达成时序收敛。

weixin_29196891的博客 299

什么叫创世区块、创世区块有什么用、为什么需要创世区块

创世区块(Genesis Block)是任何区块链技术中的第一个区块,它是区块链的起点,标志着该区块链的诞生。在创世区块之前没有任何区块存在,因此它没有前一个区块的哈希值,通常这个位置会被设置为零或者一个预定义的特殊值。创世区块包含了区块链网络的一些初始参数和规则,比如初始的难度值、时间戳、初始的交易记录等。

以择人之心择己,以恕己之心恕人。 1557

【OpenStack】OpenStack原理(一)——OpenStack发展及架构

OpenStack目前的七个核心组件,分别是计算(Compute)、对象存储(Object Storage)、认证(Identity)、用户界面(Dashboard)、块存储(Block Storage)、网络(Network)和镜像服务(Image Service)。

大数据分析BDA 2万+

以太坊源码分析(4)——初始化创世区块

一、前言 通过前面章节学习了以太坊的基本架构之后,我们通过自己搭建一个单节点,并覆盖以太坊主要流程来讲解代码。在这一节,你将学会:如何初始化创世区块 二、准备工作 以太坊源码 V 1.8.0 golang 1.9+ windows 系统下 goland 2018+ 因为本系列文章主要是研究以太坊源码,所以以太坊的编译工作不详细展开,有需要的可以参考这篇文章。 三、genesis.j...

极地大王章的专栏 1800

RH850从0搭建Autosar开发环境【1】- 如何创建Davinci Configurator配置工程

当我们在公司接触Autosar开发环境时,基本都是完整的Davinci Configurator的配置工程,我们只能修修补补。 从本章开始将手把手搭建Rh850基于Vector公司Davinci Configurator的autosar配置工程。主要涉及到OS,COM,DCMM,NVM,BSWM,ECUM等基本模块,包括Vlink,memap使用,XCP标定的实现等。基本是实现一个基础版的项目开发。包括后期的GreenHills编译问题处理,生成最终的Hex文件。

weixin_42412049的博客 1万+

开关电源-LLC基本原理

本文详细介绍了LLC谐振变换器的兴起原因、基本工作原理、变换器特点及拓扑结构。重点讨论了半桥、全桥LLC及其软开关技术,包括零电压开关(ZVS)和零电流开关(ZCS)。通过理解简单的谐振电路(RL、RC、LC)来阐述LLC如何改变电压增益,以及如何通过调节频率实现输出电压的稳定性。

让你爱上电路设计 2万+

tinychain源码解读:从创世区块到链上交易的完整流程

**tinychain**是一个极简的比特币实现,用不到700行Python代码完整再现了比特币的核心机制。本文将从**创世区块**开始,深入解析**区块链交易**的完整生命周期,带你理解这个**迷你比特币**如何实现**去中心化账本**的核心功能。无论你是区块链新手还是开发者,都能通过这个简化版本快速掌握比特币的工作原理。 ## 🔍 tinychain项目概览 tinychain是一个**

gitblog_00336的博客 330

C#调用企业微信JS-Sdk实现扫描二维码

企业微信JS-SDK是企业微信面向网页开发者提供的基于企业微信内的网页开发工具包。通过使用企业微信JS-SDK,网页开发者可借助企业微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用企业微信分享、扫一扫等企业微信特有的能力,为企业微信用户提供更优质的网页体验提示:生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是H5应用调用企业微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。

清浅 937

如何快速开始使用Prysm:新手入门教程

Prysm是以太坊权益证明(PoS)协议的Go语言实现,为开发者和用户提供了参与以太坊网络验证的完整解决方案。本教程将帮助你快速搭建Prysm环境,从安装到启动验证节点,轻松开启以太坊PoS之旅。 ## 🔍 准备工作:系统要求与依赖 在开始前,请确保你的系统满足以下条件: - 64位Linux、macOS或Windows操作系统 - 至少8GB内存和20GB可用磁盘空间 - 稳定的网络连接

gitblog_00931的博客 471

5.1 rocr-runtime libhsakmt event 机制全景—从 Doorbell 到 Signal

本文介绍了ROCm/KFD中的Event机制架构,主要解决GPU异步计算中的反馈问题。Event机制分为三层:硬件层触发事件,内核层管理事件通知,用户态接收处理。事件类型分为三大类:同步类事件(如SIGNAL、QUEUE_EVENT)用于任务完成通知,异常类事件(如MEMORY、HW_EXCEPTION)报告错误,拓扑类事件(如NODECHANGE)处理设备变更。该机制通过共享内存和中断实现高效通信,避免CPU轮询开销。后续文章将深入内核实现、Thunk层封装和多队列完成检测实战。

图形/计算GPU的驱动与虚拟化技术分享园地 1307

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

区块链开发(一)搭建基于以太坊go-ethereum的私有链环境

通过各方资料了解学习之后,决定自己开始搭建基于以太坊go-ethereum的私有链环境。由于本人的电脑系统为win8,为避免window环境出现过多莫名其妙的问题,特意通过vm搭建了一台ubuntu16.04版本的虚拟系统。以下内容均基于ubuntu16.04系统。go-ethereum客户端下载地址&参考手册首先,可以查看一下go-ethereum项目在git上的地址: https://gith

程序新视界 3万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Fabric1.4源码解析:Peer节点加入通道

又开始新的阅读了,这次看的是Peer节点加入通道的过程。其实每次看源码都会有好多没有看懂的地方,不过相信只要坚持下去,保持记录,还是有很多收获的。 对于Peer节点加入通道这一过程,从用户角度来说也只是简单执行一行命令: peer channel join -b mychannel.block 就完成了某一节点加入通道的过程。而从Fabric网络内部来讲,却是...

weixin_30768661的博客 891

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

go-ethereum(通常简称为 Geth)源码解释

go-ethereum 是一个工程杰作,代码质量很高,但体量巨大。分层思想:它清晰地分离了核心协议 (core)、网络通信 (p2p) 和应用服务 (rpc, eth)。模块化设计:每个部分都相对独立,通过接口(如 consensus.Engine)进行交互,具有很好的扩展性。数据结构是基础:不理解 Block、Transaction 和 Merkle Patricia Trie,就很难理解上层逻辑。希望这个导览能为你探索 Geth 的代码世界提供一张清晰的地图!

u011091936的博客 791

从零构建多节点以太坊私链:基于Geth与Clique PoA的实战指南

区块链网络的核心在于其去中心化与共识机制,它通过分布式节点共同维护一个不可篡改的账本。在以太坊生态中,Geth客户端是实现这一原理的关键工具,它完整实现了以太坊协议,允许开发者构建独立的网络环境。对于开发测试、教学演示或联盟链概念验证而言,搭建一个隔离的私有网络具有极高的技术价值,它能模拟真实的节点发现、交易广播与区块同步行为。本指南聚焦于使用Geth和Clique权威证明共识,详细讲解如何从创世区块配置入手,逐步完成多节点组网、互连与稳定运行,并深入解析节点无法互相发现、区块高度不一致等常见问题的解决方案

weixin_34290631的博客 722

区块链初探

区块链报告 0. 实验环境 虚拟机: ubuntu-17.10.1-desktop-amd64 go的版本: go1.11 1. 以太坊的安装,安装geth客户端 geth是用go语言写的,编译geth源码需要go语言和C语言编译器,因此需要先安装go语言,go语言版本推荐用go1.7及以上,go语言的安装配置教程。 将github仓库克隆源文件: git clone https:/...

lllllyt的博客 1979

在 python-sdk 中为 MCP 客户端接入 OAuth 2.0:OAuthClientProvider 与客户端凭据认证实战

本指南围绕官方 Python SDK(python-sdk)的 OAuth 客户端侧能力展开,讲解如何用 `OAuthClientProvider` 为受保护的 MCP Server 自动完成授权码(Authorization Code + PKCE)流程,以及用 `ClientCredentialsOAuthProvider` / `PrivateKeyJWTOAuthProvider` 实现机

gitblog_00080的博客 351

Android ServiceManager启动源码解析:Binder通信总机与系统服务注册机制

在Android系统架构中,进程间通信(IPC)是支撑系统服务与应用交互的核心机制。Binder作为Android特有的IPC框架,通过驱动层的内核模块实现高效的数据传输与进程隔离。其核心原理在于利用内存映射与引用计数机制,在保证安全性的同时实现跨进程方法调用。这一技术价值在于构建了Android系统服务的松耦合架构,使得ActivityManager、WindowManager等核心服务能够独立运行并协同工作。在应用场景中,任何系统服务的注册与发现都依赖于一个中央协调组件。ServiceManager正是

weixin_30411819的博客 456

Ubuntu 16.04源码构建Go语言工具链实战指南

Go语言工具链是现代云原生开发的基础设施,其构建原理涉及自举(bootstrapping)、交叉编译与工具链隔离等核心编译器工程概念。理解Go如何从C实现的Go 1.4启动器出发,逐步构建出纯Go实现的高版本编译器,对保障遗留系统兼容性、定制化运行时及安全合规交付具有关键价值。尤其在Ubuntu 16.04等长期支持但内核与工具链陈旧的环境中,官方二进制常因binutils版本、libc ABI或调度器内核依赖不匹配而失效。本文聚焦源码构建这一可审计、可复现的工程实践,覆盖bootstrap编译器准备、GO

weixin_30653023的博客 370

Hyperledger Fabric联盟链部署运维实战:从国赛真题到生产级搭建

区块链作为分布式账本技术的核心,通过去中心化、不可篡改和共识机制等原理,为数据可信协作提供了底层支撑。其技术价值在于构建无需中介的信任体系,在供应链金融、政务数据共享等场景实现安全透明的业务流程。企业级应用中,联盟链架构成为主流,而部署运维是保障区块链网络稳定运行的关键工程实践。本文聚焦Hyperledger Fabric这一主流联盟链平台,深入解析基于Docker Compose的容器化部署方案,涵盖证书体系、通道配置、链码生命周期等核心模块。针对运维中常见的节点启动失败、链码部署异常等高频故障,提供结合

weixin_34133829的博客 406

svn可视化工具_版本控制可视化神器Gource:简单易上手,效果恰似烟花秀

鱼羊 发自 凹非寺量子位 报道 | 公众号 QbitAI如此华丽的绽放,莫非是一场动画烟火秀?非也,这其实是GitLab社区版的进化史,7年间82000次commit,尽皆在2.5分钟的视频内展现。Python的演化历史更是鹅妹子嘤。一开始,Guido化身一个白色的小人,满屏幕风风火火地释放“光束”,让“Python树”迅速长成了茁壮发育的模样。而从92年开始,新的角色出现在了Python的成长史...

weixin_39625975的博客 354

效果酷炫!开源可视化神器:带你看尽项目的沧桑变化!

公众号关注“GitHubDaily”设为 “星标”,每天带你逛 GitHub!转自量子位,作者鱼羊如此华丽的绽放,莫非是一场动画烟火秀?非也,这其实是 GitLab 社区版的进化史,7...

GitHubDaily 840
上一篇: 从命令行开始解析同步区块的代码
下一篇: Geth代码目录详解
The_Web3_社区
博客等级 码龄10年 388粉丝 154原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

The_Web3_社区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值