https://github.com/MetaMask/metamask-extension/tree/master/app/scripts/controllers/network

metamask-extension/app/scripts/controllers/network/network.js

const assert = require('assert')
const EventEmitter = require('events')
const createMetamaskProvider = require('web3-provider-engine/zero.js')
const SubproviderFromProvider = require('web3-provider-engine/subproviders/provider.js')
const createInfuraProvider = require('eth-json-rpc-infura/src/createProvider')
const ObservableStore = require('obs-store')//ObservableStore是一个内存中的同步存储,只存储一个值,用于订阅更新。详细看https://github.com/MetaMask/obs-store
const ComposedStore = require('obs-store/lib/composed')
const extend = require('xtend')
const EthQuery = require('eth-query')
const createEventEmitterProxy = require('../../lib/events-proxy.js')
const log = require('loglevel')
const urlUtil = require('url')
const {//这就是我们在metamask中看见的五种网络
ROPSTEN,
RINKEBY,
KOVAN,
MAINNET,
LOCALHOST,
} = require('./enums')
const LOCALHOST_RPC_URL = 'http://localhost:8545' //本地网络设置的host:port信息
const INFURA_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET] //infura支持的网络的类型有这四种 const env = process.env.METAMASK_ENV //process是nodejs中的一个全局变量,metamask-extension/package.json进行METAMASK_ENV设置,设置为test
const METAMASK_DEBUG = process.env.METAMASK_DEBUG //如果之前没有设置则为false,这是在调用网页的时候进行设置的window.METAMASK_DEBUG = true
const testMode = (METAMASK_DEBUG || env === 'test') //如果满足其中之一则说明使用的是测试模式 const defaultProviderConfig = {
type: testMode ? RINKEBY : MAINNET,//如果是测试模式,则自动设置为RINKEBY,否则为MAINNET
} module.exports = class NetworkController extends EventEmitter { constructor (opts = {}) {//如果没有opts传入,则默认为{}
super() // parse options
const providerConfig = opts.provider || defaultProviderConfig
// create stores
this.providerStore = new ObservableStore(providerConfig)//即上面的provider,到底是default的RINKEBY或MAINNET还是用户自己传进来的provider
this.networkStore = new ObservableStore('loading') //network处于加载状态
this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore }) //即将两个store组合起来
// create event emitter proxy
this._proxy = createEventEmitterProxy() this.on('networkDidChange', this.lookupNetwork)
} initializeProvider (_providerParams) { //初始化provider
this._baseProviderParams = _providerParams
const { type, rpcTarget } = this.providerStore.getState() //得到此时provider的状态,type即ROPSTEN, RINKEBY, KOVAN, MAINNET四种之一,rpcTarget即连接的网络信息
this._configureProvider({ type, rpcTarget }) //配置provider,rpcTarget即比如http://localhost:8545
this._proxy.on('block', this._logBlock.bind(this))
this._proxy.on('error', this.verifyNetwork.bind(this))
this.ethQuery = new EthQuery(this._proxy)
this.lookupNetwork()
return this._proxy
} verifyNetwork () {
// Check network when restoring connectivity:
if (this.isNetworkLoading()) this.lookupNetwork()
} getNetworkState () {
return this.networkStore.getState()
} setNetworkState (network) {
return this.networkStore.putState(network)
} isNetworkLoading () {
return this.getNetworkState() === 'loading'
} lookupNetwork () {
// Prevent firing when provider is not defined.
if (!this.ethQuery || !this.ethQuery.sendAsync) {
return log.warn('NetworkController - lookupNetwork aborted due to missing ethQuery')
}
this.ethQuery.sendAsync({ method: 'net_version' }, (err, network) => {
if (err) return this.setNetworkState('loading')
log.info('web3.getNetwork returned ' + network)
this.setNetworkState(network)
})
} setRpcTarget (rpcTarget) {
const providerConfig = {
type: 'rpc',
rpcTarget,
}
this.providerConfig = providerConfig
} async setProviderType (type) {
assert.notEqual(type, 'rpc', `NetworkController - cannot call "setProviderType" with type 'rpc'. use "setRpcTarget"`)
assert(INFURA_PROVIDER_TYPES.includes(type) || type === LOCALHOST, `NetworkController - Unknown rpc type "${type}"`)
const providerConfig = { type }
this.providerConfig = providerConfig
} resetConnection () {
this.providerConfig = this.getProviderConfig()
} set providerConfig (providerConfig) {
this.providerStore.updateState(providerConfig)
this._switchNetwork(providerConfig)
} getProviderConfig () {
return this.providerStore.getState()
} //
// Private
// _switchNetwork (opts) {
this.setNetworkState('loading')
this._configureProvider(opts)
this.emit('networkDidChange')
} _configureProvider (opts) {
const { type, rpcTarget } = opts
// infura type-based endpoints
const isInfura = INFURA_PROVIDER_TYPES.includes(type)//type即infura中支持的那四种网络的类型ROPSTEN, RINKEBY, KOVAN, MAINNET,metamask的这四种网络的provider都是使用了infura
if (isInfura) {//是就调用infura配置this._configureInfuraProvider(opts)
// other type-based rpc endpoints
} else if (type === LOCALHOST) {//否则就查看它是否使用了本地的8545接口,如ganache
this._configureStandardProvider({ rpcUrl: LOCALHOST_RPC_URL })
// url-based rpc endpoints
} else if (type === 'rpc') {//或者是自己设置的其他区块链接口
this._configureStandardProvider({ rpcUrl: rpcTarget })
} else {
throw new Error(`NetworkController - _configureProvider - unknown type "${type}"`)//没有连接到这样的接口时报错
}
} _configureInfuraProvider ({ type }) {
log.info('_configureInfuraProvider', type)
const infuraProvider = createInfuraProvider({ network: type })
const infuraSubprovider = new SubproviderFromProvider(infuraProvider)
const providerParams = extend(this._baseProviderParams, {
engineParams: {
pollingInterval: ,
blockTrackerProvider: infuraProvider,
},
dataSubprovider: infuraSubprovider,
})
const provider = createMetamaskProvider(providerParams)
this._setProvider(provider)
} _configureStandardProvider ({ rpcUrl }) {
// urlUtil handles malformed urls
rpcUrl = urlUtil.parse(rpcUrl).format()
const providerParams = extend(this._baseProviderParams, {
rpcUrl,
engineParams: {
pollingInterval: ,
},
})
const provider = createMetamaskProvider(providerParams)
this._setProvider(provider)
} _setProvider (provider) {
// collect old block tracker events
const oldProvider = this._provider
let blockTrackerHandlers
if (oldProvider) {
// capture old block handlers
blockTrackerHandlers = oldProvider._blockTracker.proxyEventHandlers
// tear down
oldProvider.removeAllListeners()
oldProvider.stop()
}
// override block tracler
provider._blockTracker = createEventEmitterProxy(provider._blockTracker, blockTrackerHandlers)
// set as new provider
this._provider = provider
this._proxy.setTarget(provider)
} _logBlock (block) {
log.info(`BLOCK CHANGED: #${block.number.toString('hex')} 0x${block.hash.toString('hex')}`)
this.verifyNetwork()
}
}

metamask-extension/app/scripts/controllers/network/enums.js

有关网络的配置信息

const ROPSTEN = 'ropsten'
const RINKEBY = 'rinkeby'
const KOVAN = 'kovan'
const MAINNET = 'mainnet'
const LOCALHOST = 'localhost'

//各个网络的networkId值
const MAINNET_CODE =
const ROPSTEN_CODE =
const RINKEYBY_CODE =
const KOVAN_CODE =

//各个网络在metamask上的显示名字
const ROPSTEN_DISPLAY_NAME = 'Ropsten'
const RINKEBY_DISPLAY_NAME = 'Rinkeby'
const KOVAN_DISPLAY_NAME = 'Kovan'
const MAINNET_DISPLAY_NAME = 'Main Ethereum Network' module.exports = {
ROPSTEN,
RINKEBY,
KOVAN,
MAINNET,
LOCALHOST,
MAINNET_CODE,
ROPSTEN_CODE,
RINKEYBY_CODE,
KOVAN_CODE,
ROPSTEN_DISPLAY_NAME,
RINKEBY_DISPLAY_NAME,
KOVAN_DISPLAY_NAME,
MAINNET_DISPLAY_NAME,
}

metamask源码学习-controllers-network的更多相关文章

  1. metamask源码学习-ui/index.js

    The UI-即上图左下角metamask-ui部分,即其图形化界面 The MetaMask UI is essentially just a website that can be configu ...

  2. metamask源码学习导论

    ()MetaMask Browser Extension https://github.com/MetaMask/metamask-extension 这就是整个metamask的源码所在之处,好好看 ...

  3. metamask源码学习-metamask-controller.js

    The MetaMask Controller——The central metamask controller. Aggregates other controllers and exports a ...

  4. metamask源码学习-controller-transaction

    ()metamask-extension/app/scripts/controllers/transactions Transaction Controller is an aggregate of ...

  5. metamask源码学习-inpage.js

    The most confusing part about porting MetaMask to a new platform is the way we provide the Web3 API ...

  6. metamask源码学习-background.js

    这个就是浏览器后台所进行操作的地方了,它就是页面也区块链进行交互的中间部分. metamask-background描述了为web扩展单例的文件app/scripts/background.js.该上 ...

  7. metamask源码学习-contentscript.js

    When a new site is visited, the WebExtension creates a new ContentScript in that page's context, whi ...

  8. MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)

    前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...

  9. MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)

    前言:上篇介绍了下自己的MVC框架前两个版本,经过两天的整理,版本三基本已经完成,今天还是发出来供大家参考和学习.虽然微软的Routing功能已经非常强大,完全没有必要再“重复造轮子”了,但博主还是觉 ...

随机推荐

  1. DataTable的一个简单的扩展

    我们在调试代码的时候经常遇到DataTable的数据类型错误,这个类可以帮助我们很快查看DataTable的结构信息. /// <summary> /// DataTable扩展类 /// ...

  2. 【Spring】4、Spring中 @Autowired标签与 @Resource标签 的区别

    转自:http://blog.csdn.net/angus_17/article/details/7543478 spring不但支持自己定义的@Autowired注解,还支持由JSR-250规范定义 ...

  3. 【读书笔记】iOS-属性中的内存管理参数

    一,assign 代表设置时候直接赋值,而不是复制或者保留它. 二,retain. 会在赋值的时候把新值保留.此属性只能用于Object-C对象类型. 三,copy 在赋值时,将新值复制一份,复制工作 ...

  4. Expo大作战(三十五)--expo sdk api之Location!

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  5. springcloud 入门 11 (Hystrix Dashboard)

    hystrix: 断路器我在前面已经介绍,不了解的可以参考 :springcloud 入门 6 (断路器hystrix)  关于搭建,测试我都在这里面进行说明了,这章介绍的是  Hystrix Das ...

  6. Python:GUI之tkinter学习笔记3事件绑定

    相关内容: command bind protocol 首发时间:2018-03-04 19:26 command: command是控件中的一个参数,如果使得command=函数,那么点击控件的时候 ...

  7. 使用wxpy来实现自动发送消息统计微信好友信息的功能

    发送消息太频繁会出现禁言消息 1:导入wxpy模块 pip install wxpy pip3 install wxpy #二者选一 调用模块 # 导入模块 from wxpy import * # ...

  8. 从零自学Java-9.描述对象

    1.为类或对象创建变量:2.使用对象和类的方法:3.调用方法并返回一个值:4.创建构造函数:5.给方法传递参数:6.使用this来引用对象:7.创建新对象. 程序VirusLab:测试Virus类的功 ...

  9. 安装Linux Mint 17后要做的20件事

    Linux Mint 17 Qiana Cinnamon Linux Mint 17已经发布,定名为Qiana.Mint是Linux最佳发行版之一,它定位于桌面用户,关注可用性和简洁.它携带了风格迥异 ...

  10. c#中ofType的用法

    原文:http://www.cnblogs.com/Janzen/p/5128749.html 该关键字主要用在非泛型到泛型之间的转化,在有些场合还是很有用的:比如:在使用非泛型的时候,想使用LINQ ...