ETH源码学习(2)GetBalance
从这开始读,因为最简单。还能对重要的东西有所理解。如果是单节点debug,重启链之后余额会归零,所以最少要两个节点,同步区块就没这个问题了,具体原因还未知。 声明:eth版本:Geth/v1.10.7-unstable/darwin-arm64/go1.17.5,我对比了网上的一些文章,这块代码有改动,主要以下改变从BlockChain的snap中读account几乎放弃从trie中获取account,判断极为严苛,我想不到有什么情况能进入,应该是放弃了这层分析入口//命令 eth.getBalance('0x0d7dd6dbabee2ec9b325aa7aa8b42d75068e8597') //入口 func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { //获取statedb state, _, err := s.b.StateAndHea...
Ether.js+Web3modal基础使用
1.说明现在网站会提供很多种钱包,web3modal可以提供统一的provider,不需要你操心太多东西用ether.js而不是web3.js的原因是简单,爽2.安装npm i web3modal npm i ethers //另外还需要安装对应wallet的包,自行搜索就行 3.连接钱包// MM默认就有,无需显式加入 const providerOptions = { walletconnect: { package: walletconnectProvider, options: { infuraId: "", }, }, }; //构建Web3Modal对象 const web3Modal = new Web3Modal({ //缓存provider cacheProvider: true, providerOptions, }); //连接wallet async function connect() { try { const web3ModalProvider = await web3Modal.connect(); provider = new ethers.pr...
ETH源码学习(1)创建私有链
下载geth,创建genesis.json{ "config": { "chainId": 8888, //自行修改 "homesteadBlock": 0, "daoForkBlock": 0, "daoForkSupport": true, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "ethash": {} }, "nonce": "0x42", "timestamp": "0x0", "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", "gasLimit": "0xffffffff", "difficulty": "0x700000",//难度,越大挖矿越慢 "alloc": { "093f59f1d91017d30d8c2caa78feb5beb0d2cfaf...
ETH源码学习(2)GetBalance
从这开始读,因为最简单。还能对重要的东西有所理解。如果是单节点debug,重启链之后余额会归零,所以最少要两个节点,同步区块就没这个问题了,具体原因还未知。 声明:eth版本:Geth/v1.10.7-unstable/darwin-arm64/go1.17.5,我对比了网上的一些文章,这块代码有改动,主要以下改变从BlockChain的snap中读account几乎放弃从trie中获取account,判断极为严苛,我想不到有什么情况能进入,应该是放弃了这层分析入口//命令 eth.getBalance('0x0d7dd6dbabee2ec9b325aa7aa8b42d75068e8597') //入口 func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { //获取statedb state, _, err := s.b.StateAndHea...
Ether.js+Web3modal基础使用
1.说明现在网站会提供很多种钱包,web3modal可以提供统一的provider,不需要你操心太多东西用ether.js而不是web3.js的原因是简单,爽2.安装npm i web3modal npm i ethers //另外还需要安装对应wallet的包,自行搜索就行 3.连接钱包// MM默认就有,无需显式加入 const providerOptions = { walletconnect: { package: walletconnectProvider, options: { infuraId: "", }, }, }; //构建Web3Modal对象 const web3Modal = new Web3Modal({ //缓存provider cacheProvider: true, providerOptions, }); //连接wallet async function connect() { try { const web3ModalProvider = await web3Modal.connect(); provider = new ethers.pr...
ETH源码学习(1)创建私有链
下载geth,创建genesis.json{ "config": { "chainId": 8888, //自行修改 "homesteadBlock": 0, "daoForkBlock": 0, "daoForkSupport": true, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "ethash": {} }, "nonce": "0x42", "timestamp": "0x0", "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", "gasLimit": "0xffffffff", "difficulty": "0x700000",//难度,越大挖矿越慢 "alloc": { "093f59f1d91017d30d8c2caa78feb5beb0d2cfaf...
Subscribe to point
Subscribe to point
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers
通过上篇getBalance和这个getBlock,理论上eth也能变成一个中心化的服务,因为用户和交易最终也都是保存到了数据库,那就和我们平时开发的项目没什么区别。这还蛮有意思的,eth实际上是区块链+传统项目的结合体。
//命令
eth.getBlock(1,true)
//跳过了前面几层
func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
//用block number换block的hash
hash := rawdb.ReadCanonicalHash(bc.db, number)
if hash == (common.Hash{}) {
return nil
}
//根据hash和number获取block
return bc.GetBlock(hash, number)
}
//获取hash
func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash {
//这个还没弄明白
data, _ := db.Ancient(freezerHashTable, number)
if len(data) == 0 {
//从db中读
data, _ = db.Get(headerHashKey(number))
if len(data) == 0 {
data, _ = db.Ancient(freezerHashTable, number)
}
}
if len(data) == 0 {
return common.Hash{}
}
return common.BytesToHash(data)
}
//获取区块
func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
//从缓存中读,这里用到了lur
if block, ok := bc.blockCache.Get(hash); ok {
return block.(*types.Block)
}
//从db中读,内容和getbalance一样,里面是先获取header,再获取body,然后创建区块,将header和body copy到block返回
block := rawdb.ReadBlock(bc.db, hash, number)
if block == nil {
return nil
}
//缓存区块
bc.blockCache.Add(block.Hash(), block)
return block
}
两篇get方法都是大同小异,进一步了解到eth是可以很简单的实现的,那些很牛逼的东西,都是为了满足区块链、性能这些需求。
另外这篇内容的主要代码都在blockchain内,又一次出现了这个,说明很重要,而statedb却没有出现,目前可以猜测statedb和账户有关,和block无关,需要后续验证。
也能知道leveldb里大致存的内容
用户数据
header
number→hash
body,body里存了tx,uncle
可以想象还有receipt
//block的例子
{
difficulty: 1461115576915,
extraData: "0x476574682f76312e302e312f6c696e75782f676f312e342e32",
gasLimit: 22150,
gasUsed: 21000,
hash: "0xeecb25ce31fb7a212500443a31d463b663a2c5f65e7838c5364bb8110a0750f1",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x47ff6576639c2e94762ea5443978d7681c0e78dc",
mixHash: "0xaaad7bf5c87f1b2fc08ed73a1519dae6832b458a112891cd7c5a0a86125a8321",
nonce: "0x4e164418632effd2",
number: 46251,
parentHash: "0x3c93a7ff6fb6f39e63456e9ea6fb069c7783f3c00b1012e36f0a8a02bdae604a",
receiptsRoot: "0x5add83c7805c02ab079871e3a2379b6a764d34e557d758ddce00b6a1bf5cc79f",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 652,
stateRoot: "0x7692ecfeac33453620701bad9eae23f89c01e845274f0e5adec78a5ea96f5083",
timestamp: 1438919990,
totalDifficulty: 42835839136947252,
transactions: [{
blockHash: "0xeecb25ce31fb7a212500443a31d463b663a2c5f65e7838c5364bb8110a0750f1",
blockNumber: 46251,
from: "0xfd2605a2bf58fdbb90db1da55df61628b47f9e8c",
gas: 21000,
gasPrice: 88893746891,
hash: "0x304346de678ddca5b1311970e7e8d3f26a42d2924aaa2f2d73b8781a9a9a2c73",
input: "0x",
nonce: 1,
r: "0x26f3e5c541f526b549d9f003c8e7de442d3cf4bbf9c66934027672693a88275f",
s: "0x7bd40d54be85b58444d6f0a28f22591474a84380fc8a6a7515bda42b5ebb0e2b",
to: "0x073f70b5bfade6409e4951ef72bc8f4157677729",
transactionIndex: 0,
v: "0x1c",
value: 10000000000000000
}],
transactionsRoot: "0xf642520ac0ce7008292d2c835b8d2e6eb90822f8a68b8ae368b0774229371b5d",
uncles: []
}
通过上篇getBalance和这个getBlock,理论上eth也能变成一个中心化的服务,因为用户和交易最终也都是保存到了数据库,那就和我们平时开发的项目没什么区别。这还蛮有意思的,eth实际上是区块链+传统项目的结合体。
//命令
eth.getBlock(1,true)
//跳过了前面几层
func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
//用block number换block的hash
hash := rawdb.ReadCanonicalHash(bc.db, number)
if hash == (common.Hash{}) {
return nil
}
//根据hash和number获取block
return bc.GetBlock(hash, number)
}
//获取hash
func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash {
//这个还没弄明白
data, _ := db.Ancient(freezerHashTable, number)
if len(data) == 0 {
//从db中读
data, _ = db.Get(headerHashKey(number))
if len(data) == 0 {
data, _ = db.Ancient(freezerHashTable, number)
}
}
if len(data) == 0 {
return common.Hash{}
}
return common.BytesToHash(data)
}
//获取区块
func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
//从缓存中读,这里用到了lur
if block, ok := bc.blockCache.Get(hash); ok {
return block.(*types.Block)
}
//从db中读,内容和getbalance一样,里面是先获取header,再获取body,然后创建区块,将header和body copy到block返回
block := rawdb.ReadBlock(bc.db, hash, number)
if block == nil {
return nil
}
//缓存区块
bc.blockCache.Add(block.Hash(), block)
return block
}
两篇get方法都是大同小异,进一步了解到eth是可以很简单的实现的,那些很牛逼的东西,都是为了满足区块链、性能这些需求。
另外这篇内容的主要代码都在blockchain内,又一次出现了这个,说明很重要,而statedb却没有出现,目前可以猜测statedb和账户有关,和block无关,需要后续验证。
也能知道leveldb里大致存的内容
用户数据
header
number→hash
body,body里存了tx,uncle
可以想象还有receipt
//block的例子
{
difficulty: 1461115576915,
extraData: "0x476574682f76312e302e312f6c696e75782f676f312e342e32",
gasLimit: 22150,
gasUsed: 21000,
hash: "0xeecb25ce31fb7a212500443a31d463b663a2c5f65e7838c5364bb8110a0750f1",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x47ff6576639c2e94762ea5443978d7681c0e78dc",
mixHash: "0xaaad7bf5c87f1b2fc08ed73a1519dae6832b458a112891cd7c5a0a86125a8321",
nonce: "0x4e164418632effd2",
number: 46251,
parentHash: "0x3c93a7ff6fb6f39e63456e9ea6fb069c7783f3c00b1012e36f0a8a02bdae604a",
receiptsRoot: "0x5add83c7805c02ab079871e3a2379b6a764d34e557d758ddce00b6a1bf5cc79f",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 652,
stateRoot: "0x7692ecfeac33453620701bad9eae23f89c01e845274f0e5adec78a5ea96f5083",
timestamp: 1438919990,
totalDifficulty: 42835839136947252,
transactions: [{
blockHash: "0xeecb25ce31fb7a212500443a31d463b663a2c5f65e7838c5364bb8110a0750f1",
blockNumber: 46251,
from: "0xfd2605a2bf58fdbb90db1da55df61628b47f9e8c",
gas: 21000,
gasPrice: 88893746891,
hash: "0x304346de678ddca5b1311970e7e8d3f26a42d2924aaa2f2d73b8781a9a9a2c73",
input: "0x",
nonce: 1,
r: "0x26f3e5c541f526b549d9f003c8e7de442d3cf4bbf9c66934027672693a88275f",
s: "0x7bd40d54be85b58444d6f0a28f22591474a84380fc8a6a7515bda42b5ebb0e2b",
to: "0x073f70b5bfade6409e4951ef72bc8f4157677729",
transactionIndex: 0,
v: "0x1c",
value: 10000000000000000
}],
transactionsRoot: "0xf642520ac0ce7008292d2c835b8d2e6eb90822f8a68b8ae368b0774229371b5d",
uncles: []
}
No activity yet